In a recent project I'm using a lot of databinding and xml-serialization. I'm using C#/VS2008 and have downloaded symbol information for the .NET framework to help me when debugging.
The app I'm working on has a global "catch all" exception handler to present a more presentable messages to users if there happens to be any uncaught exceptions being thrown. My problem is when I turn on Exceptions->Thrown to be able to debug exceptions before they are caught by the "catch all". It seems to me that the framework throws a lot of exceptions that are not immediately caught (for example in ReflectPropertyDescriptor) so that the exception I'm actually trying to debug gets lost in the noise. Is there any way to get rid of exceptions caused by the framework but keep the ones from my own code?
Update: after more research and actually trying to get rid of the exceptions that get thrown by the framework (many which turn out to be known issues in the framework, example: XmlSerializer giving FileNotFoundException at constructor) I finally found a solution that works for me, which is turning on "Just my code" in Tools >> Options >> Debugging >> General >> Enable Just My Code in VS2008.
You can fine tune which types of exceptions are caught in which way through the Exceptions dialog in VS2008, but If the frame work is throwing "a lot of exceptions" you might want to look into that as well. Just because an exception is handled doesn't mean that it's safe, or that it's not robbing your performance.
One way to filter exceptions thrown by the framework is to derive your own exception classes from Exception. You can then use multiple catch blocks:
try
{
//your code here
}
catch (MyAppException myEx)
{
//Do something with your custom exception
}
catch (Exception ex)
{
//Do something (or nothing) with an exception thrown by the Framework
}
It might be worth your while to get rid of catch-all exceptions as it is not exactly good programming technique. For an example, if you are working with Input Output such as file reading/writing, trap the IOException instead of the more generic Exception, another example is XmlException for any XML manipulation. Using a catch-all generic Exception may yield a performance hit as the specific exception has to "bubble up" up to the generic Exception Handler.
Hope this helps,
Best regards,
Tom.
Related
I have asked a few questions on here and read a few articles around exception handling but don't think I'm really grasping when you should and when you shouldn't handle an exception. From the articles I've read it states to "only handle exceptions you can recover from" What does it mean by that. If I can't handle the exception what do I do? Let it propagate back up the stack? If I don't handle it how can I log it and present a user friendly error message. What do most people do in web apps and web services?
As an example say I have a lower tier data layer that pulls data from sql
try{
//do something with db
}catch(SqlException ex){
//what should i do here
//should i call code again to retry getting data from db
}catch(Exception ex){
//should i even catch exception of type exception
}
How do I handle exceptions in lower tiers? Should I just let the exception bubble up the tiers? If so then if I want to catch an exception of type sqlexception then I need a reference to the library sqlexception is part of but surely I shouldn't have to reference that library in a layer that has nothing to do with data access.
Some simple ground rules:
Handling an exception requires that the state of your program is exactly the same as it was before the code got started that caused the exception. You will need lots of catch and finally blocks that restore variables back to their initial state.
Only consider handling an exception if catching it allows the program to continue running in a meaningful way. Hard to do anything useful when the database server is off line for example, might as well stop the program.
If you need a human to take corrective action (you almost always do) then be sure that she has enough information to troubleshoot the problem. Let exceptions bubble up to the UI layer. Avoid interpreting exceptions (no "Could not update the database" for example), display the exact exception message and stack trace.
Implement a handler for AppDomain.CurrentDomain.UnhandledException and log or display the value of e.ExceptionObject. Helps to diagnose unhandled exceptions. And helps you avoid putting catch everywhere.
A hundred unhandled exceptions with a good diagnostic is better than one caught one that destabilizes the program so it generates bad data or causes other unrelated exceptions to be thrown.
Exception management is a large subject, so I'll only touch the surface here.
From the articles ive read it states to "only handle exceptions you can recover from" What does it mean by that.
If you don't know how to recover from a specific exception, then there's not usually any point in catching it. If it's a web app or service, the web server itself will deal with the logging and recovery.
In some cases, you need to catch exceptions so that you can a generic recovery, for example by cancelling or reversing a transaction. In that case, an acceptable approach is to
catch the exception, do the generic recovery, and then throw the exception again.
If i cant handle the exception what do i do. Let it propgate back up the stack?
Yes.
If i dont handle it how can i log it and present a user friendly error message. What do most people do in web apps and web services?
The web server will log the exception. If you want to present a user-friendly error message in a web app, you can catch/log at the highest level of the stack and re-direct to your error message. Again, I would try not to catch System.Exception - instead make a list of the exceptions that your app throws, and catch just these types before presenting a message tailored to each type. As the list of exception types grows, either prevent each new exception type by changing the code, or add a new catch for that exception type.
In a web service, you can create a custom exception and add that as a node to the generic exception that the web service will provide.
In your code example, I wouldn't use try...catch unless you're expecting an exception and you know what to do with it.
How do i handle exceptions in lower tiers. Should i just let the exception bubble up the tiers.
Yes.
Okay, this will be far too brief since it's still early in the morning here but i've been struggling with this same question so here is what I understand:
"only handle exceptions you can recover from"
My understanding here is that you get the exception to a level in your code where you can do something about it. In the case of your low level code, you would let the exception bubble back up into a layer where you could modify your 'process' to handle the exception and possibly try the process again. (I typically log the error right where it is thrown.)
I have a function that looks like this:
try
{
_dbManager.InsertSearch(some data);
}
catch (Exception ex)
{
//do logging
}
_dbManager uses LINQ to insert data to a SQL database. Yesterday, the machine that hosts the database ran out of hard disk space and my program crashed. I got a crash dump which shows that there was a SqlClient.SqlException raised with an exception message reading something like "Database transaction log is full...".
My question is: Why didn't the exception get caught in the catch block above? The weird thing is, when I tried to reproduce the issue, I could get the same exception, but it was caught by the catch block. What could be the issue?
Second, related question: Imagine if we use a third party library and we don't want any exception thrown. We can use try-catch block, but this only works on calling thread. What if the third party starts new thread and an exception is thrown there? Is there a way to handle this? I know I can register our UnhandledExceptionHandler, but that seems to be a different from what I wanted.
My question is: Why didn't the exception get caught in the catch block above?
As David Stratton suggests, the system might have been out of disk space and not able to write to log file. There is also a chance that the process was terminated due to Corrupted State Exception that will not be delivered to your catch-all block in .NET 4. The exception that terminated process might have also been thrown from the thread that did not have catch-all.
Second, related question: Imagine if we use a third party library and
we don't want any exception thrown.
I think that you will have to stop right there and rethink it. What you saying is that you are absolutely 100% sure that nothing ever can go wrong in the thirdparty library. There are certain exceptions (like OutOfMemoryException) that you should not be catching because your code simply does not know how to recover from them. The rule of thumb with exception handling is that you should only catch the exceptions that you fully understand and know how to recover from. Please take a look at this answer and the links in it.
What if the third party starts new thread and an exception is thrown
there? Is there a way to handle this?
The best way to handle this is to rely on default CLR policy that will terminate your application. The only reasonable thing you can do is try to log it by subscribing to AppDomain.UnhandledException.
Is it possible that there is another try/catch block inside that InsertSearch method, which has conditional throw statement.
The implementer of the 'DBManager' class, chose not to throw in case there is not enough space to write on the disk. Just a thought.
If you use Code contracts runtime checking I advice you to check compiled version of your DLL.
Read this for details Why .net exception is not caught?
I'm using VS2008 and have ReSharper too.
My question is how can I automate the creation of a try/catch block for which the catch is specifically populated with the possible exception from the try block? (i.e. not just put in an Exception ex)
Background - Trying to help follow the best practice I read of "Don't catch (Exception) more than once per thread. Good code throws exceptions as needed, and handles only the exceptions it knows how to handle."
thanks
To do that I think you would need a tool that recursively walks your code (and the code it calls, and so forth), and figures out which exceptions could possibly be thrown.
Redgate has a tool that does this. However, I think you probably have a fair idea in your code of what possible exceptions it might throw, and the BCL has decent documentation that says what exceptions might possibly be thrown by any given method you call in the BCL, so it's probably not too hard at the local level to figure out what you need to handle and what you don't.
From what I've read, this was one of the major reasons why the C# team chose not to implement checked exceptions similar to Java - they wanted to discourage this kind of exception non-handling.
There is no means of intrinsically automating such an operation in Visual Studio, nor should you try; if you don't know how to handle a particular exception, then don't catch it just because the library might throw it.
In addition, there are all sorts of special-case system exceptions that might be thrown by the framework, like OutOfMemoryException, BadImageFormatException, AppDomainUnloadedException and so on, that aren't directly thrown by the particular method you're invoking but bubble through it from the .NET runtime. If you wanted to catch all possible exceptions then you'd have to catch these as well, but for the most part it would be a fruitless exercise since there's not much you can do when you get a StackOverflowException - and again, you generally shouldn't attempt to.
In conclusion, the best way to write exception handlers for library methods (and any other methods) is to read the documentation on said method, which will tell you what exceptions you can expect it to throw, and then catch only the ones you actually expect and/or know how to handle. Do not catch the generic System.Exception unless you want spectacular crashes and mysterious data corruption late into the production cycle.
I have a service that seems to die once in a while. I have tried catching the unhandled exception (using appDomain method) but to no avail.
Looking at my code, I can see exception handling code around certain places. However, there is not exception handling code when I am writing to a log file via enterprise library.
My questions is, should I put exception handling around the enterprise library code in case it throws an exception or is it reliable enough to handle any problems?
JD,
What will you do if the logging block does throw an exception? You obviously can't log it so I would say no, don't catch that exception. Only catch exceptions that you can handle and do something meaningful with - a caught exception around logging simply means that you will be hiding the fact that real errors are not getting logged.
We're reviewing one of the company's system's exception handling and found a couple of interesting things.
Most of the code blocks (if not all of them) are inside a try/catch block, and inside the catch block a new BaseApplicationException is being thrown - which seems to be coming from the Enterprise Libraries.
I'm in a bit of a trouble here as I don't see the benefits off doing this. (throwing another exception anytime one occurs)
One of the developers who's been using the system for a while said it's because that class's in charge of publishing the exception (sending emails and stuff like that) but he wasn't too sure about it.
After spending some time going through the code I'm quite confident to say, that's all it does is collecting information about the environment and than publishing it.
My question is:
- Is it reasonable to wrap all the code inside try { } catch { } blocks and than throw a new exception? And if it is, why? What's the benefit?
My personal opinion is that it would be much easier to use an HttpModule, sign up for the Error event of the Application event, and do what's necessary inside the module. If we'd go down this road, would we miss something? Any drawbacks?
Your opinion's much appreciated.
Never1 catch (Exception ex). Period2. There is no way you can handle all the different kinds of errors that you may catch.
Never3 catch an Exception-derived type if you can't handle it or provide additional information (to be used by subsequent exception handlers). Displaying an error message is not the same as handling the error.
A couple of reasons for this, from the top of my head:
Catching and rethrowing is expensive
You'll end up losing the stack trace
You'll have a low signal-to-noice ratio in your code
If you know how to handle a specific exception (and reset the application to pre-error state), catch it. (That's why it's called exception handling.)
To handle exceptions that are not caught, listen for the appropriate events. When doing WinForms, you'll need to listen for System.AppDomain.CurrentDomain.UnhandledException, and - if your doing Threading - System.Windows.Forms.Application.ThreadException. For web apps, there are similar mechanisms (System.Web.HttpApplication.Error).
As for wrapping framework exceptions in your application (non-)specific exceptions (i.e. throw new MyBaseException(ex);): Utterly pointless, and a bad smell.4
Edit
1 Never is a very harsh word, especially when it comes to engineering, as #Chris pointed out in the comments. I'll admit to being high on principles when I first wrote this answer.
2,3 See 1.
4 If you don't bring anything new to the table, I still stand by this. If you have caught Exception ex as part of a method that you know could fail in any number of ways, I believe that the current method should reflect that in it's signature. And as you know, exceptions is not part of the method signature.
If I am reading the question correctly, I would say that implementing a try / catch which intercept exceptions (you don't mention - is it catching all exceptions, or just a specific one?) and throws a different exception is generally a bad thing.
Disadvantages:
At the very least you will lose stack trace information - the stack you will see will only extend to the method in which the new exception is thrown - you potentially lose some good debug info here.
If you are catching Exception, you are running the risk of masking critical exceptions, like OutOfMemory or StackOverflow with a less critical exception, and thus leaving the process running, where perhaps it should have been torn down.
Possible Advantages:
In some very specific cases you could take an exception which doesn't have much debug value (like some exceptions coming back from a database) and wrap with an exception which adds more context, e.g id of the object you were dealing with.
However, in almost all cases this is a bad smell and should be used with caution.
Generally you should only catch an exception when there is something realistic that you can do in that location- ie recovering, rolling back, going to plan B etc. If there is nothing you can do about it, just allow it to pass up the chain. You should only catch and throw a new exception if there is specific and useful data available in that location which can augment the original exception and hence aid debugging.
I'm from the school of thought where try/ catch blocks should be used and exceptions not rethrown. If you have executing code which is likely to error then it should be handled, logged and something returned. Rethrowing the exception only serves the purpose to re-log later in the application life cycle.
Here's an interesting post on how to use a HttpModule to handle exceptions: http://blogs.msdn.com/rahulso/archive/2008/07/13/how-to-use-httpmodules-to-troubleshoot-your-asp-net-application.aspx and http://blogs.msdn.com/rahulso/archive/2008/07/18/asp-net-how-to-write-error-messages-into-a-text-file-using-a-simple-httpmodule.aspx
Check out ELMAH. It does what you're talking about. Very well.
When I create libraries I try to always provide a reduced number of exceptions for callers to handle. For example, think of a Repository component that connects to a sql database. There are TONS of exceptions, from sql client exceptions to invalid cast exceptions, that can theoretically be thrown. Many of these are clearly documented and can be accounted for at compile time. So, I catch as many of them as I can, place them in a single exception type, say a RepositoryException, and let that exception roll up the call stack.
The original exception is retained, so the original exception can be diagnosed. But my callers only need to worry about handling a single exception type rather than litter their code with tons of different catch blocks.
There are, of course, some issues with this. Most notably, if the caller can handle some of these exceptions, they have to root around in the RepositoryException and then switch on the type of the inner exception to handle it. Its less clean than having a single catch block for a single exception type. I don't think thats much of an issue, however.
Sounds like the exception that is thrown should not have been implemented as an exception.
Anyway, I would say that since this BaseApplicationException is a general all-purpose exception, it would be good to throw exceptions that are more context-specific. So when you are trying to retrieve an entity from a database, you might want an EntityNotFoundException. This way when you are debugging you do not have to search through inner exceptions and stack traces to find the real issue. If this BAseApplicationException is collecting information on the exception (like keeping track of the inner exception) then this should not be a problem.
I would use the HttpModule only when I could not get any closer to where the exceptions are actually happening in code. You do not really want an HttModule OnError event that is a giant switch statement depending on BaseApplicationexception's error information.
To conclude, it is worth it to throw different exceptions when you can give more specific exceptions that tell you the root of the problem right off the bat.
From my experience, catch the exception, add the error to the Server (?) object. This will allow .NET to do what ever it needs to do, then display your exception.