Wednesday, October 10, 2007

Handle All Application Errors, Log Them in Event Viewer, and Show a Friendly Message

I'm working on a simple way in an ASP.NET 2.0 website to 1) catch all application errors that are otherwise uncaught, 2) log these errors in the Event Viewer, and 3) display a friendly error message to the user when these errors occur, while trying to keep this code all in as few places as possible. Here's what I'm doing now. I'll modify this post if I change.

In global.asax I added:
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
/* Error information will be written to the Event Viewer logs and not displayed
* to the user. The error page will present a friendlier message. */
string fullError = "An error occurred. The page was: " + Request.Url.PathAndQuery + ". " +
"The message was: " + Server.GetLastError().Message + ". " +
"The stack trace was: " + Server.GetLastError().StackTrace + ". ";

/* We don't clear the error here so we can display it on the error page
* when tracing is enabled. The error is cleared there. */
//Server.ClearError();

System.Diagnostics.EventLog eLog = new System.Diagnostics.EventLog("Application", ".");
// Application is the log to use, . is the local machine.
eLog.Source = "MyApp";
eLog.WriteEntry(fullError, System.Diagnostics.EventLogEntryType.Error);

Server.Transfer("~/error.aspx");
}

In error.aspx I added:
 
using System.Diagnostics;

public partial class error : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Trace.Write("ERROR: " + Server.GetLastError().Message);
/* Clear error here, not in Global.asax because
* we want to put it in the trace messages. */
Server.ClearError();
}
}

In testerror.aspx, a page that intentionally throws an error to test the setup, I added:

protected void Page_Load(object sender, EventArgs e)
{
// This throws an exception so we can test logging to the event viewer.
throw (new ArgumentNullException());
}

No comments: