Catching Exceptions in background threads with Elmah - asp.net

I have an MVC+SignalR application that has a lot of Reactive Extensions subscriptions flying around, all of which are projections of data coming from a Socket in realtime. Some of these subscriptions are not working as expected, and when they raise an exception it just goes into the void unless I'm debugging.
I had hoped that I could use Elmah to automatically log these unhandled exceptions, but it seems that unless the exception occurs on the same thread that's processing the request/response, eg it causes a yellow screen of death, Elmah isn't touching it. So my question is twofold:
Can I get Elmah to automatically log exceptions on background/worker processes?
If the answer to #1 is "no", what's my next best option, other than wrapping my subscriptions in try/catch blocks at a very high level?

Ad 1) If it doesn't happen already it probably doesn't.
I don't know how exactly you use background threads, but I will try to explain were ELMAH handling is working. ELMAH is integrated into ASP.NET pipeline, and when the error occurs it is handled by ASP.NET pipeline, which shows error page (like http error 500) and invoke ErrorLogModule. Moreover quoting Using HTTP Modules and Handlers to Create Pluggable ASP.NET Components -> Adding ELMAH to an ASP.NET Web Application
The section adds the ErrorLogModule HTTP module to the
ASP.NET HTTP pipeline. Make sure you include this
setting, otherwise ELMAH won't be listening for the Error event, and
therefore won't be logging any unhandled exceptions.
Ad 2) Because you are using Reactive Extensions you can handle onError in which you can automatically log into Elmah. If you don't want to writer everywhere error hangling in OnError, just create your own function or method extension which will wrap it automatically for you. Writing into ELMAH manually is simple just call:
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);

Related

Difference between ELMAH and Global.asax exception handling

I have website and I need to log exceptions globally, cannot understand what is difference between using ELMAH as error logging mechanism or use Application_Error in Global.asax, I think that all will log all exceptions thrown, or I'm missing something about ELMAH
ELMAH subscribes to the same Error event that Application_Error in Global.asax is designed to handle. As a result, you will not be at any more disadvantage with Application_Error than ELMAH as far as getting notified when an unhanded exception bubbles up to ASP.NET during an HTTP transaction. The difference is that except for very simplistic logging, if your needs ever expand to configurability, filtering errors, generating RSS feeds or building a browsing UI around logged errors then you'll pretty much end up writing the same code in your Application_Error as ELMAH gives you. If you plan to use that code in Application_Error of other web applications, then it will need to be generalised and rendered pluggable and that, once again, will give you what ELMAH already is.

How to implement ELMAH in an ASP.NET web app that uses extensive try/catch blocks?

We have an ASP.NET webforms app that has try/catch blocks all throughout. In the catch block, it calls a method that sends an email containing limited information about the error thrown.
We want to implement ELMAH in this app, but ELMAH only works with unhandled exceptions (based on my experiences, at least). What I would like to do is, instead of removing all the try/catch blocks from the app, replace the code within the method that sends the email with a call to ELMAH that will force ELMAH to send an email as if the exception were unhandled. It would look just like the regular email, complete with stack trace, authenticated user, referring URL, etc.
If you handle the exception, ELMAH will not receive it.
ELMAH is not designed to be a full logging framework but to work alongside one, such a log4net.
Instead of trying to force ELMAH into this role, consider using a dedicated logging framework for your handled exceptions.
You can signal ELMAH from your handling code if you really need to, as described in this answer to does elmah handle caught exceptions as well:
ErrorSignal.FromCurrentContext().Raise(ex);

Should I catch all my exceptions in the global.asax?

If I am just logging exception details in my web app, do I really need to put in exception handling logic for each tier? Why not just let them all bubble up the stack trace to the global.asax and log them there?
I would suggest against using any exception handling logic in any layer of your application unless:
The exception is not a fatal one, meaning that there is some action you can take to recover, or
The application should continue functioning and the exception should be "ignored." An example: when checking out at an online retailer you are sent a receipt via email. If that fails - but the other order processing stuff succeeds - the user should not be shown an error page. Here, we want the workflow to continue even though there is an exception. Most exceptions do not fall into this category.
Of course, exceptions - whether they are fatal or not or should be "ignored" or not - need to be logged and developers notified. This is best handled through an event handler for the Application.Error event. Yes, this can be done in Global.asax, but I think it's cleaner to use an HTTP Module-based approach, either Health Monitoring or ELMAH.
I've written an article on this topic that I'd like to recommend to you - Exception Handling Advice for ASP.NET Web Applications. Here is the article in summary:
My advice for handling exceptions in an ASP.NET application can be boiled down to the following guidelines:
(a) Create and use a meaningful custom error page.
(b) In general, do not catch exceptions. Let them bubble up to the ASP.NET runtime. Some cases where catching an exception makes sense include:
When there is a plausible way to recover from the exception by performing some alternative logic,
When a peripheral part of the application's workflow throws and exception and that exception should not derail the entire application, and
When you need to include additional information with the exception by throwing a new exception that has the original exception as its inner exception.
(c) Log all exceptions to some persistent store and use email (or some other medium) to notify developers when an exception occurs in production. Consider using ELMAH or ASP.NET's built-in Health Monitoring system to facilitate this process.
Exceptions should bubble up to whatever layer can handle them in a meaningful way, being aware of the Single Responsibility principle. For instance, your data layer should not be invested in logging.
The Application.Error event is a good place for catch-all error handling: that is, unexpected and/or fatal errors that require no special treatment beyond logging/alerting and redirecting to an error page.
If your web app makes use of the Microsoft AJAX extensions and partial postbacks, you'll need to handle exceptions in at least two places:
Global.asax
Your ScriptManager's OnAsyncPostBackError handler
For further information on OnAsyncPostBackError, check out:
http://msforge.net/blogs/janko/archive/2008/02/13/handling-exceptions-in-asp-net-ajax.aspx
http://msdn.microsoft.com/en-us/library/system.web.ui.scriptmanager.onasyncpostbackerror.aspx
I say that on global try to catch the error that you miss on the logic steps of your program and redirect them on an "error page", or a "not found page".
All other errors not necessary show the error on the user, and not need to send it to an error page.
For example, in page with 2 or more, different modules, if the one throw an error, just hide it, and show the rest. Similar try to catch errors when they happens and handle them the best non visual way to the user if this is possible, log them and correct them later.
Now this error that happens only on one module, you can see it on your log and correct it, but until you do that, user see something on your page and not a full error page.
Usually what I do is do a try...catch in the code, but instead of logging on the catch what I do is pass it on with a message stating where the error came from, etc. Then I use Elmah to catch all of the errors and log them.
That way you only have to deal with the logging in one area and satisfy the Single Responsiblity Principle, but you have more information available for debugging purposes. It can also be helpful when you get that data error that only seems to occur with 1 out of 500 users.

Exception handling in a three-tier Asp.Net application

1) To my understanding, in a three-tier Asp.Net application we should implement exception handling in the following way:
a - we should put try-catch block around block of code ( located in any of the three layers ) from which we expect the page to gracefully recover from ( when this code generates an exception )?
b - we shouldn’t put try-catch blocks around code ( located in either of the three layers ) from which we don’t expect the page to gracefully recover from. Instead, Asp.Net application should always manage these unhandled exceptions through global exception handler ( Application_Error/Page_Error )?
2) Is the main benefit of managing unhandled exceptions through Application_Error/Page_Error the fact that this way we centralize error handling in one location?
After all, we could achieve the same results even if these unhandled exceptions (thrown in any of the three layers ) were instead handled ( logged, user redirected to custom error page ... ) at the spot where they were thrown?!
thank you
Not necessarily.
1a - it's quite acceptable for the data layer to have no exception handling. In which case any exception would be handled further up the stack.
1b - the data layer and business layer may not be called via a website, so a particular web page isn't necessarily relevant. For example, a webservice or WPF application may also use these layers.
2 - yes the main benefit is a single location for website error handling.
The main thing you want to avoid is silently swallowing exceptions that cannot be recovered from. (In short, having a try...catch block where you display some error to the user, but don't rethrow the exception, where thereby only the end user is aware that something went awry.)
If an exception happens and you can recover from it, great!
If an exception happens and you can't recover from it, then it is important that the exception details be logged and that the developers are notified of the exception. Typically this is done by letting the exception propagate to the ASP.NET runtime layer so that ASP.NET's Error event will fire. It's a best practice to subscribe to this Error event in some manner so as to log the error details and notify developers. One such tool for logging and notifying in the face of an error is ELMAH, another is the ASP.NET Health Monitoring library.
Also, if I may, I'd suggest this article of mine, which covers the points I made in here more depth and detail: Exception Handling Advice for ASP.NET Web Applications.
Happy Programming!
1a) is correct.
1b) is sort of correct; you may let the exception go up the stack from your model/business layers to the presentation, and display an error message. It doesn't have to go all the way to the Application_Error; Page_Error may be good, but some exceptions might be (relatively) common enough that, while you can not gracefully recover, you should have specific error messages related to them in some contexts.
2) basically; and also as a 'catch all' for exceptions you have not been able to predict and catch in more specific places.

How to handle WCF exceptions in ASP.NET

I'm working on a traditional ASP.NET application making WCF service calls.
Should I put a try catch around the WCF call and display the error details at the top of the current page; let the error redirect the user to a custom error page; or leave it up IIS / .NET framework?
Which approach is least likely to confuse future developer?
Never to the yellow screen of death. The detailed information about the error can give hints to a hacker to break your site.
If the page cannot be displayed without the service request, then redirect to a custom error page.
If only a small portion of information will be missing on a page which is not key to its function, then better display a friendly message to the user that this particular piece of information is not available at the moment.
This will depend on your application requirements. Can you continue processing if the web service call fails? If not you probably should log the exception and redirect the user to a 500 page. I would use Application_Error method in global.asax to do this. If you can continue the processing then you should put a try/catch around your web service call and handle the appropriate FaultException. You should never let customers see the yellow screen in production.
If you expect that the WCF call can throw an exception and you know which exception types you can get, then yes, you should catch the exception and perform the appropriate action. Usually it is a good idea to tell the user just that an error made the operation to fail, and log the exception detail for further examination by you or the technical support.

Resources