I have seen several posts around the web where people have created custom error handling code in the global.asax file. The problem a lot of developers seem to come across is obtaining the actual line number where the error occured.

The main issue I have seen is developers using the following code to obtain information on the error that has occured:

System.Exception myError = Server.GetLastError();

This is where they are going wrong. The above code gives information on the last error that has been recorded as the event bubbles up through the layers, and not the information that was recorded when the actual error occured. The following line of code will obtain the Exception object describing the original error:


System.Exception myError = Server.GetLasteError().GetBaseException();

When an error occurs in my applications I like to send an email to myself with the error information and also write to a log file located on the server. Below is an example of the code I use in the global.asax file to achieve this:


void Application_Error(object sender, EventArgs e) 
{ 
    // Code that runs when an unhandled error occurs
    if (System.Configuration.ConfigurationManager.AppSettings.Get("SYS_ERROR_LOG_ACTIVE") == "YES") {
        System.Exception myError = Server.GetLastError().GetBaseException();
            
        //Do not send email if error is page not found
        if (myError.Message.IndexOf("does not exist.") == -1)
        {
             HttpContext con = HttpContext.Current;
             System.Diagnostics.StackTrace myStack = new System.Diagnostics.StackTrace(true);

             CreateLogFiles Err = new CreateLogFiles();
             Err.ErrorLog("Offending URL: " + con.Request.Url.ToString() + Environment.NewLine +
             "Source: " + myError.Source + Environment.NewLine +
             "Message: " + myError.Message + Environment.NewLine +
             "--- Full Error --- " + Environment.NewLine + myError.StackTrace.ToString());

             //Create MailDefinition

             System.Web.UI.WebControls.MailDefinition md = new MailDefinition();
             md.IsBodyHtml = false;

             System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage("SENDER EMAIL ADDRESS", "RECIPIENT EMAIL ADDRESS");
             msg.Subject = ConfigurationManager.AppSettings.Get("SYS_ADMIN_SITE_NAME") + "Error Details";
             msg.Body = "Offending URL: " + con.Request.Url.ToString() + Environment.NewLine +
             "Source: " + myError.Source + Environment.NewLine +
             "Message: " + myError.Message + Environment.NewLine +
             "--- Full Error --- " + Environment.NewLine + myError.StackTrace.ToString();

             System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient();
             smtp.Send(msg);   
         }
     }
}

If anyone has any questions on the use of this code, fire away.