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.
Related
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);
In my ASP.NET MVC3 application I want all unexpected problems logged. So I have logging inside Application_Error(). Also I found there's Controller.OnException() method and so I made an override for my controllers that log the error and then call base.OnException().
Looks like every time an exception occurs in a controller action my OnException() override is called and then Application_Error() is called and so logging is performed twice.
If I eliminate my OnException() override and only leave logging in Application_Error() will I still log all the problems or will I miss any kind of events?
Controller.OnException() is MVC specific. Application_Error() is ASP.NET specific. MVC sits on top of ASP.NET, so if you handle the exception in Controller.OnException(), you may want to set ExceptionContext's ExceptionHandled to true so that it doesn't propagate down the pipeline into Application_Error().
You're right in that every error can be allowed to propagate to the Application_Error() level and handled there. It really depends on choice and preference I think. I see it both ways. I see the benefit in handling action method specific errors in Controller's OnException and other errors when the request does not even reach the controller (e.g. start-up errors, 404s) in Application_Error. When you have a hybrid app that uses both MVC and web forms, then Application_Error has to be used for web forms errors.
So while handling exceptions in Application_Error() is a must-have for making sure your app doesn't have uncaught exceptions, using Controller.OnException() is a matter of preference for handling a specific subset of errors.
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);
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.
I can't figure out why the exception from a static ASP.Net Page method isn't bubbling up to the Application_Error event to be handled in the global.asax file. I'm not really expecting any errors, but I would like to be safe and know about them if they do happen to occur and would rather not wrap every static method in a try...catch.
Does anyone know how to catch these exceptions or at least why they aren't bubbling?
Exceptions bubble to the error handler in Application_Error if they are not being handled in the lower layers. If you already have a TRY/CATCH block where you think the exception is occurring, it will be trapped at that point.
Please post the code of your static method and your Application_Error. It will make it easier to provide you with an accurate answer instead of a generalized one.
If developing in Visual Studio, you should debug your code and then step through the source to find the exception and see what is catching it before bubbling up to your Application_Error method.