We all desire some custom exception handling techniques for our web application. You probably want some friendly message to show up in a page; and you'd just want one page for this. If you have come from a Windows Forms background, you might have come across the Exception
class. If you initialize the exception
class with a specific string
(a user friendly message), you see the same message while you debug or while you handle and display the exception details. Unfortunately, this manner of exception handling won't do any good for your web application. So let this be a point if you wanted to differentiate a web application from a Windows application.
Custom Error Pages - What Are They?
Here are some little things to keep in mind before you dive into 'redirecting' to custom error pages. This section does not deal with exception handling. With custom error pages, I think the most to expect here is a static page. That's it, a static page! Then why do we need it? I've visited http://forums.asp.net (it's the official forum for ASP.NET) web site on many occasions. On that web site (or web application if you will) if requests encounter some error, you get redirected to an error page. (Click here to see an example). There is a line that politely goes like, "Please be assured that we log and review all errors. Even if you do not report this error, we will endeavor to correct it." So ultimately, I think they persist the details of the error somewhere or the web site developers are intimated the details of the error.
- Set the
customErrors
mode to 'On
' or 'RemoteOnly
' in the web.config
Here you are trying to specify a redirection page in case error occurs. The difference between the two is that with 'On
', you specify that you want some sort of redirection no matter from which machine you work. With 'RemoteOnly
', the page will get redirected if the browser application was running from a remote machine rather than the local machine (where you host your web app).
<configuration>
<system.web>
<customErrors mode="On">
</customErrors>
</system.web>
</configuration>
- Application level page redirection
You can write your custom page that shows a friendly error message here. And in case an error occurs and it goes improperly handled, this page will show up no matter what. Most usually, this is simply a static page (.htm or .html). For this, the following setting is necessary.
<customErrors mode="On" defaultRedirection="~/Error.htm"/>
One thing you have to take note here is, in case of an unhandled exception, your browser is "redirected" to this page. The error page is served to you as if you had requested it. It is the same thing as using Response.Redirect()
in your code. It gets served on a different request pipeline; not in the same one the error causing page was processed in.
- Page level redirection
This is almost similar to the above. The difference is that you can set the error page redirection at page level instead of doing so at the application level. What is set at page level will override the application level settings if any. But you still need to have your custom error mode to 'On
', and your page directive as follows:
<%@ Page ErrorPage="http://www.cymru-web.net/GenericError.htm" %>
Exception Handling
Most people will actually prefer the error message itself to appear on the error page. Sometimes, we may want to show a generic static page, and yet still want to receive a complete detail of the exception via email, or we would want it logged somewhere. This is quite possible. The trick is trying not to redirect to the error page, but to actually get it served through the same request pipeline.
And like before, you can have this on either a page level or at an application level.
- Page Level Exception Handling
If there is an unhandled exception in a page and you want to handle that error in the page itself, you have to handle the Page_Error
event that gets triggered.
Protected Sub Page_Error(ByVal sender as Object, ByVal e as EventArgs) Handles Page.Error
Context.ClearError()
End Sub
It is important to call Context.ClearError()
because it ensures that the unhandled exception does not propagate/escalate to the application level.
- Application Level Exception Handling
If there is an exception that goes unhandled in the Global.asax file or .aspx file, you can handle those errors from the Global.asax itself. The Application_Error
event gets triggered whenever an exception is not trapped anywhere within your web application.
Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
End Sub
Things You Can Do in an Error Event Sub
I'd generally say, "your error logging/handling routines go here". It's up to you. You can save the information to a database, have it emailed to you, save it to the windows event log, etc. There are some things that you'd have to do with care. Like for example, if you are storing the error information to one text file, you'd have to write the code in such a way that is thread-safe. Sometimes, you'd have to queue the IO request because some other thread may be using the text file. (Here, we make use of technologies like MS Message Queue). All this is so because your ASP.NET application runs in a multi-threaded environment where many requests are served concurrently. Essentially, this means the same code is executing in one application domain, but it serves many users. This is in stark contrast to a Windows Forms application where a thread (or many threads) executes for one user.
Final Words
Error handling in my opinion is not straight forward. Mostly, this is because we don't realize that ASP.NET was designed to execute in a multi-threaded environment. I've discussed 90% about handling errors, but I have not discussed how to display the exception details in your custom error page. More specifically, how to expose the exception object (which caused the exception) in the custom error page. Well, all I hope is that I finish it earlier.