ASP.NET Error Handling

Introduction
When developing a site there are bound to be occasions when despite our best efforts, errors will occur. ASP.NET has some built in facilities for handling this like custom error pages. In practice, however, we often need more information about the error so we can address the issue.

Custom Page Class
While a MasterPages might seem to be the obvious place to handle application errors, a Master Page only really behaves like a master page up to rendering then essentially acts like a user control. Also, it is quite possible that you would have several master pages in any web application. With that in mind the more logical approach would be the custom page class.

How
To make a custom page class you simply create a new class in the app_code folder which inherits from the System.Web.Page class, then, you simply override the OnError event and implement your error handling code. My weapon of choice is email, as it is pretty instantaneous and allows you to act quickly in response to potential problems (I do not operate on the ignorance is bliss development process!). Lastly you make all your aspx pages inherit from your custom page class.


using System.Web

public class CustomPage : Page
{
protected override void OnError(EventArgs e)
{
base.OnError(e);
var ex = Server.GetLastError();
var hc = HttpContext.Current;

var requestUrl = hc.Request.Url.ToString();
var emailSender = “senders email address goes here ”;
var emailSubject = "error @ site: " + requestUrl;
const string emailRecipient = "your email address goes here";

var sb = new StringBuilder();

// include information about the current web request
sb.AppendFormat("Time: {0}\n", DateTime.Now.ToString("g"));
sb.AppendFormat("URL: {0}\n", requestUrl);
sb.AppendFormat("Is HTTPS: {0}\n", hc.Request.IsSecureConnection);
sb.AppendFormat("URL Referrer: {0}\n", hc.Request.UrlReferrer);
sb.AppendFormat("Server Name: {0}\n", hc.Request.ServerVariables["SERVER_NAME"]);
sb.AppendFormat("QueryString: {0}\n", hc.Request.QueryString);
sb.AppendFormat("Platform: {0}\n", hc.Request.Browser.Platform);
sb.AppendFormat("Is Crawler: {0}\n", hc.Request.Browser.Crawler);
sb.AppendFormat("User Agent: {0}\n", hc.Request.UserAgent);
sb.AppendFormat("Supports Cookies: {0}\n", hc.Request.Browser.Cookies);
sb.AppendFormat("User IP: {0}\n", hc.Request.UserHostAddress);
sb.AppendFormat("User Host Name: {0}\n", hc.Request.UserHostName);
sb.AppendFormat("User is Authenticated: {0}", hc.User.Identity.IsAuthenticated);
sb.AppendFormat("\n\n");

var message = ex.Message;

while (ex != null)
{
sb.AppendFormat("Message: {0}\n", message);
sb.AppendFormat("Source: {0}\n", ex.Source);
sb.AppendFormat("TargetSite: {0}\n", ex.TargetSite);
sb.AppendFormat("StackTrace: {0}", ex.StackTrace);
sb.AppendFormat("\n\n");

ex = ex.InnerException;
}
var m = new MailMessage(emailSender, emailRecipient, emailSubject, sb.ToString());

var smtp = requestUrl.Contains("localhost")
? new SmtpClient("localhost")
: new SmtpClient(“smtp server address goes here usually localhost for most hosting companies”);

smtp.Send(m);
Response.Redirect(“your error url goes here”);
}
}


Explanation
In the above code quite a lot of information has been collected in addition to the basic error messages which can be very useful when trying to detect the problem. Also, the code digs down into the inner exceptions so that you see all of the bubbled exceptions. Lastly the user is redirected to a user friendly error page of your choice; this means that you are not exposing your users to the standard ASP.NET error pages which are meaningless to anyone except the developer of the application.