On a .NET exam I encountered this question.
Which of the following can you use to catch unhandled exceptions in an application?
Server_Error
Page_Error
Application_Error
Response_Error
OnError event
I know its Application_Error, But what I want to know is what are the others. By some google search I found OnError can be used to catch any errors. Still I am not sure about it. Could you tell what are the other ways to catch unhandled exception
The correct point to catch your unknown errors is the Application_Error.
Avoid to capture the OnError on your page, and let the system transfer it to the Application_Error because there you have lost the control on the page, so what other you can do if not transfer it to some error page ? - if you try to just reload it you have the problem to be in a close loop that can cause stack overflow.
From my experience I have issue when I try to handle errors using the page OnError and I use it only when I have to free some global memory, or something like that if an error happens on page.
To give a summary, try to catch all your errors inside a try/catch block, and give a message to your user / or just take care of this issues, but let the unknown errors to the global catcher to log it and fix it. The unknown errors is something that make you lose the real control of your program, and actually you do not know what to do because you do not have predict it - so log it and fix it for the next time
More details about the errors :
How do I make a "generic error" page in my ASP.NET application so that it handles errors triggered when serving that page itself?
Related
I am on my way to my first bigger project in ASP.Net.
I want to know how to catch, and where to catch, the error when the database is not available. Let's say a community site in which you have, from beginning to end, lots of database queries. Maybe a few outsourced in other helper classes, some in the DataAccess-Layer and maybe 1 or 2 directly from Front-End.
How and where can it be caught in a good and consistent way?
This might depend on the actionsyou would like to take when this exception occurs but a good place is to use the global error handler Application_Error (in global.asax) which is called every time an unhandled exception is thrown and where you log the error and redirect the user to some page.
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.
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.
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.
I admit it: I don't bother with too much exception handling. I know I should do more but I can never wrap my head around where to start and where to stop. I'm not being lazy. Far from it. It's that I'm overwrought with exception handling ambivalence. It just seems that there is a seemingly infinite number of places in even the smallest app where exception handling can be applied and it can begin to feel like overkill.
I've gotten by with careful testing, validating, and silent prayer but this is a bad programming accident waiting to happen.
So, what are your exception handling best practices? In particular, where are the most obvious/critical places where exception handling should be applied and where are places where it should be considered?
Sorry for the vague the question but I really want to close the book on this once and for all.
Microsoft's Patterns & Practices team did a good job incorporating best practices of exception management into Enterprise Library Exception Handling Application Block
Event if wouldn't use Enterprise Library, I highly recommend you to read their documentation. P&P team describes common scenarios and best practices for exceptions handling.
To get you started I recommend read following articles:
Exception Handling on MSDN
Exception Management in .NET on MSDN
Exception Handling Best Practices in .NET on CodeProject
ASP.NET specific articles:
User Friendly ASP.NET Exception Handling
Global Exception Handling with
ASP.NET
Exception handling in C# and ASP
.Net
The golden rule with exception handling is:
"Only catch what you know how to handle"
I've seen too many try-catch blocks where the catch does nothing but rethrow the exception. This adds no value. Just because you call a method that has the potential to throw an exception doesn't mean you have to deal with the possible exception in the calling code. It is often perfectly acceptable to let exceptions propagate up the call stack to some other code that does know what to do.
In some cases, it is valid to let exceptions propagate all the way up to the user interface layer then catch and display the message to the user. It might be that no code is best-placed to know how to handle the situation and the user must decide the course of action.
I recommend you start by adding a good error page that catches all exceptions and prints a slightly less unfriendly message to the user. Be sure to log all details available of the exception and revise that. Let the user know that you have done this, and give him a link back to a page that will (probably) work.
Now, use that log to detect where special exception handling should be put in place. Remember that there is no use in catching an exception unless you plan to do something with it. If you have the above page in place, there is no use in catching database exceptions individually on all db operations, unless you have some specific way to recover at that specific point.
Remember: The only thing worse than not catching exceptions, is catching them and not doing nothing. This will only hide the real problems.
Might be more about exception handling in general than ASP.NET speific but:
Try to catch exceptions as close to
the cause as possible so that you
can record (log) as much information
about the exception as possible.
Include some form of catch all, last
resort exception handler at the
entry points to your program. In
ASP.NET this could be the
Application level error handler.
If you don't know how to "correctly" handle an exception let it bubble up to the catch all handler where you can treat it as an "unexpected" exception.
Use the Try***** methods in .NET
for things like accessing a
Dictionary. This helps avoid major
performance problems (exception
handling is relatively slow) if you
throw multiple exceptions in say a
loop.
Don't use exception handling to
control normal logic of your
program, e.g. exiting from a loop via
a throw statement.
Start off with a global exception handler such as http://code.google.com/p/elmah/.
Then the question comes down to what kind of application are you writting and what kind of user experience do you need to provide. The more rich the user experience the better exception handling you'll want to provide.
As an example consider a photo hosting site which has disk quotas, filesize limits, image dimension limits, etc. For each error you could simply return "An error has occured. Please try again". Or you could get into detailed error handling:
"Your file is to large. Maximum
filesizes is 5mb."
"Your image is is
to large. Maximum dimensions are
1200x1200."
"Your album is full.
Maximum storage capacity is 1gb".
"There was an error with your
upload. Our hampsters are unhappy.
Please come back later."
etc. etc.
There is no one size fits all for exception handling.
Well at the very basic level you should be handling the HttpApplication.Error event in the Global.asax file. This should log any exception that occurs to a single place so you can review the stack trace of the exception.
Apart from this basic level you should ideally be handling exceptions where you know you can recover from them - for example if you expect a file might be locked then handling the IOException and reporting the error back to the user would be a good idea.