Introduction
Recently, while going through exception handling and logging, I found an interesting topic that I would like to share, "Exceptions", that is a family member of every language/technology used. These are sometimes irritating for developers. If it's irritating for developers, what would be the condition of the end user when he/she views the yellow screen populated with God knows what!.
Now the question is, should they be displayed with that entire stack trace that is sometimes helpful for developers to resolve errors? The answer obviously is no.
Here is a small tip that might be handy. Here, I am trying to detail the use of "Custom Errors" and its attributes and elements. Web.config, the main settings and configuration for an ASP.NET web application, is the file where the custom errors find its existence. According to MSDN, custom error elements provide information about custom error messages. The main motive here is to display the end-user custom error pages. First, let's understand how the custom errors are written in the web.config (as we know in XML format):
<customerrors mode="On">
The Modes Used
On
- Prevents the stack trace that is shown when exceptions occur
- Also allows to display custom error pages to the end user
- Custom error pages are shown to both Remote Clients as well as Local
Off
- Makes the end-user view the description of the exception along with the entire stack trace.
- ASP.NET error/exception and stack trace is shown to both remote and local clients.
Remote Only
This is the best among all for the developers' perspectives, since this allows the Remote clients to view the custom error messages/pages.
Allows the local users, especially developers, to view the ASP.NET errors.
This is the default value.
Some More Facts
Another attribute that is used is "defaultRedirect". This is an optional attribute that is used to redirect the browser to the default error page if any, else generic errors are shown to the users.
<customerrors defaultredirect="Error/Index" mode="">
- This is the best amongst all from the developers' perspective, since this allows the remote clients to view the custom error messages/pages.
- Allows the local users, especially developers, to view the ASP.NET errors.
- This is the default value.
- There are also child elements used inside the scope of the customErrors. The one I have encountered and used is the error element. This might be handy if there is a requirement to show specific error pages for specific HttpStatusCodes (401,404,500).
- <customerrors defaultredirect="" mode="">
- <error statuscode="400" redirect="NotFound.htm">
- <error statuscode="500" redirect="InternalServerError.htm">
Another important thing to note is Custom Errors that can be defined in the following two levels:
- Application Level: Where we use customErrros as described above
- Page Level: Where we define in the Page directive, in other words, for specific pages. Use of the "ErrorPage" attribute is done here.
We also handle exceptions in Global.asax, in other words using:
- protected void Application_Error(Object sender, EventArgs e)
- {
- Exception ex = Server.GetLastError();
- Server.ClearError();
-
- Response.Redirect("");
- }
Now the precedence is as follows.
Quote:
When all are defined, the Page Level will have the higher precedence than global.asax and customErrors. And if the customErrors are also defined as well as in Global.asax, then customErrors will have no effect and if no exception handling is done in the global.asax, then Web.config that is customErrorscome into action.
Points of Interest
Note
- Flexibility is greater in Global.asax since we can redirect the user anywhere we want and also we can log the exceptions into DB/Azure BLOBs for writing code on the server side.
- Also, if in the application, only one generic error page is required to be shown then it's better to handle inGlobal.asax, else if as per status codes then customErrors in Web.config is better.
- When using Handling in Global.asax, remember that the exception object needs to be retrieved before the user gets redirected to the custom error page. Thus if not retrieved in the Global.asax, the exception object is lost and Server.GetLastError() returns null.
- For a better understanding, if Global.asax has only:
- protected void Application_Error(Object sender, EventArgs e)
- {
- Response.Redirect("HandleException.htm");
- }
And in the ErrorController.cs and here in the method, we try to retrieve the error object, then we get null.
- The reason behind this is the flow. When the exception occurs, it tries to be handled in the global.asax Application_Error method (the preceding written method) that only redirects the user to Error/HandleException and the user lands here on redirection only because of the error, thus the error is lost once the user is redirected.
Here, I end this. Thanks for reading. I hope you learned something from this.