views:

498

answers:

3

This question is kind of related to Handle URI hacking gracefully in ASP.NET in that it's too about how to best handle exceptions that occur during an ASP.NET request lifecycle. I've found a way to handle most exceptions gracefully, but then I've found that some exceptions occur so late in the request that there's no way to do stuff like Server.Transfer to compartementalize the whole error presentation logic into its own page.

So, I have to handle the exception inside the Application_Error event instead, and do Response.Writes and whatnot. It's ugly. I understand that in some circumstances the response stream could have already been flushed, so transferring the request isn't really an option. What I want to ask is if there's anyone who's found an elegant solution to this problem?

Also, I find it difficult to know when I can handle the exception gracefully by transferring the request to another page and not. What is the best way to find out where in the request lifecycle we're at when an exception occurs? If it occurs during the loading and rendering of a page, Page_Error will be able to handle it and I've not had a problem doing Server.Transfer there yet. But if the exception occurs either too early or too late for Page_Error to catch it and it bubbles to Application_Error, what do I do to know whether it's early or late?

If it's late in the lifecycle, I'll probably have to do Response.Write directly from Application_Error, but if it's early I can do Server.Transfer. The problem is that trying to do Server.Transfer will itself cause an exception if it's too in the request to do it.

So, is there a global enumeration or something similar that will indicate whether it's too late to do creative stuff with the response or not?

A: 

I think my advice for this would be to use ASP.NET Health Monitoring with WMI Events provider for the errors:

Here is a how to.

http://msdn.microsoft.com/en-us/library/ms178713.aspx

Hope this helps:

Andrew

REA_ANDREW
Hi, and thanks for the suggestion.An external console application won't really help as what I want is not only to catch the error (which I already do quite fine), but display a friendly error message as well.
asbjornu
Are you using the Custom Error Pages? This allows you to display custom information based on any of the Http Status Code which are thrown based on the result of any request?
REA_ANDREW
ASP.NET redirects all requests to the error pages (instead of doing Server.Transfer, for instance), so that's unusable.
asbjornu
+1  A: 

I have used this approach to catch all errors generated, either in web controls or pages. All it requires you to do is to inherit from a base class (one for pages and one for usercontrols) each page or usercontrol can implement its own HandleException method and do whatever it needs to do. Full code here:

http://stackoverflow.com/questions/280412/transparent-generic-exception-handling-for-asp-net-moss2007-with-code

AndreasKnudsen
This is basically what I did. Thanks for the suggestion.
asbjornu
A: 

I suggest that you use asp.net configuration to have a general error page for the unhandled exceptions. From the sample web.config

 <!--
        The <customErrors> section enables configuration 
        of what to do if/when an unhandled error occurs 
        during the execution of a request. Specifically, 
        it enables developers to configure html error pages 
        to be displayed in place of a error stack trace.

    <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
        <error statusCode="403" redirect="NoAccess.htm" />
        <error statusCode="404" redirect="FileNotFound.htm" />
    </customErrors>
    -->

On the overall handler, just log the exception, and let asp.net do the redirect.

If you still want to go on with your customer approach, I suggest you look at the available asp.net source and check how it is doing that.

eglasius
ASP.NET's custom errors is utterly useless as it physically redirects (via 301 or 302 response codes) the user to a new URL. Basic RESTful design and common sense says that the URL should stay the same to reflect what resource failed; redirecting breaks that completely.
asbjornu