ASP.NET provides HttpApplication.Error event and more easily accessible predefined Application_Error handler that can be used to trap errors. Logging is an important part of the error handling process, but the WebToolkit provides a few tools that provide a complete error handling solution, albeit not quite generic. This approach requires a number of interrelated configuration and helper components to handle logging, error detail display and notification.
The following is the sample implementation provided:
protected void Application_Error(object sender, EventArgs e)
{
try
{
Exception serverException = Server.GetLastError();
WebErrorHandler errorHandler;
// Try to log the inner Exception since that's what
// contains the 'real' error.
if (serverException.InnerException != null)
serverException = serverException.InnerException;
errorHandler = new WebErrorHandler(serverException);
// Log the error if specified
if (LogManagerConfiguration.Current.LogErrors)
{
errorHandler.Parse();
WebLogEntry entry = new WebLogEntry(serverException, this.Context);
entry.Details = errorHandler.ToString();
LogManager.Current.WriteEntry(entry);
}
// Retrieve the detailed String information of the Error
string ErrorDetail = errorHandler.ToString();
// Optionally email it to the Admin contacts set up in WebStoreConfig
if (!string.IsNullOrEmpty(App.Configuration.AdminEmailAddress))
AppUtils.SendAdminEmail(App.Configuration.ApplicationTitle + "Error: " + Request.RawUrl, ErrorDetail, "");
// Debug modes handle different error display mechanisms
// Default - default ASP.Net - depends on web.config settings
// Developer - display a generic application error message with no error info
// User - display a detailed error message with full error info independent of web.config setting
if (App.Configuration.DebugMode == DebugModes.DeveloperErrorMessage)
{
Server.ClearError();
MessageDisplay.DisplayMessage("Application Error", "<pre class='body'>" + ErrorDetail + "</pre>");
return;
}
else if (App.Configuration.DebugMode == DebugModes.ApplicationErrorMessage)
{
string StockMessage =
"The Server Administrator has been notified and the error logged.<p>" +
"Please continue on by either clicking the back button or by returning to the home page.<p>" +
"<center><b><a href='" + App.Configuration.ApplicationHomeUrl + "'>Web Log Home Page</a></b></center>";
// Handle some stock errors that may require special error pages
HttpException httpException = serverException as HttpException;
if (httpException != null)
{
int HttpCode = httpException.GetHttpCode();
Server.ClearError();
if (HttpCode == 404) // Page Not Found
{
Response.StatusCode = 404;
MessageDisplay.DisplayMessage("Page not found",
"You've accessed an invalid page on this Web server. " +
StockMessage);
return;
}
if (HttpCode == 401) // Access Denied
{
Response.StatusCode = 401;
MessageDisplay.DisplayMessage("Access Denied",
"You've accessed a resource that requires a valid login. " +
StockMessage);
return;
}
}
// Display a generic error message
Server.ClearError();
Response.StatusCode = 500;
MessageDisplay.DisplayMessage("Application Error",
"We're sorry, but an unhandled error occurred on the server. " +
StockMessage);
return;
}
return;
}
catch(Exception ex)
{
// Failure in the attempt to report failure - try to email
if (!string.IsNullOrEmpty(App.Configuration.AdminEmailAddress))
{
AppUtils.SendAdminEmail(App.Configuration.ApplicationTitle + "Error: " + Request.RawUrl,
"Application_Error failed!\r\n\r\n" +
ex.ToString(), "");
}
// and display an error message
Server.ClearError();
Response.StatusCode = 200;
MessageDisplay.DisplayMessage("Application Error Handler Failed",
"The application Error Handler failed with an exception." +
(App.Configuration.DebugMode == DebugModes.DeveloperErrorMessage ? "<pre>" + ex.ToString() + "</pre>" : ""));
}
}
There are a number of support classes at work and they are provided in the examples and the provided project template.
WebErrorHandler
This is a class that takes a server error exception and creates a fully qualified error report object for you. It retrieves the call stack, active line of code in much the same way that ASP.NET's yellow screen of death does but without exposing that content to the browser. This is useful so you can log the error information properly, email it and if in a flagged debug mode you can display it even if errors are off.
AppUtils
AppUtils is a class that contains a host of static methods that wrap a few common operations. Here the class is used to handle sending of emails which are provided via various versions of SendAdminEmail. The wrapper methods on this class automatically pull email send information out of configuration objects so your application code doesn't have to configure email functionality each time.
MessageDisplay
The MessageDisplay class provides the abililty to create a generic error page with custom text content, which is what's needed after an error to display some sort of controlled error page.
AppSettings
The AppSettings class handles various configuration options. Among them is a flag that determines how errors should be handled from default (ASP.NET error default), ApplicationErrorMessage ( essentially a static Sorry page) and DeveloperErrorMessage (displays similar info as ASP.NET's error page even when errorDisplay on).
Because all of these objects interact in this particular handler there's no clean way to abstract this functionality into a module for example since unless all items are configured and available this won't work. Hence this implementation sticks to an Application_Error handler that can be customized as needed by removing/enhancing the functionality provided.
© West Wind Technologies, 1996-2016 • Updated: 12/19/15
Comment or report problem with topic