Catch most derived exceptions? - c#

In .NET, when catching exceptions, should I always catch derived exceptions (so not ArgumentException but the derived types)?
Also:
If I am asked to use error codes, would this be in the constructor like so?:
throw new Exception("4000", ex);
Or a custom exception type with an errorcode property? (This may get confusing with exception types like SqlException which have error codes mapping to SQL Server errors).
Thanks

Catch the broadest exception that you know how to handle.
In general, this means you'll be catching a pretty specific exception. And some exceptions, like ArgumentExceptions, shouldn't be caught at all b/c they indicate a logic error as opposed to a runtime error. One place where I've found catching a broader exception useful is in the case of File I/O. An IOException can be a practical higher-level exception to catch.
If you are asked to use error codes, you could get away with using the message property of an exception to wrap it, but I would never use that as a reason to avoid throwing an appropriately typed exception. This is because there are two separate concerns here:
a. The error code is there to provide a specific piece of information that can be looked up in the case of a failure in the field. It should never be used to discriminate between exception types programmatically b/c the language has a specific facility designed for that: exception types.
b. The appropriately typed exception is there to provide a programmatic way of distinguishing between exceptions. The language is designed for it, use it. Don't ever throw a plain Exception.
I would probably throw an error code into the Exception.Data collection. This avoids overwriting messages in Exception.Message that would otherwise be very helpful for diagnostic purposes.

This depends on if you want to catch an exact exception or a group of different types of exceptions.
Sometimes you want to add handling for 1 exact exception only. Other times your exception handling will be the same for any type of exception so you can just put catch or just catch Exception to see what the exception is.
For example you may want to catch only 1 exact exception and no other exception handling. You would do that when you know further up the call stack you are catching the rest of the exceptions but you want to ignore just the one you're catching exactly.

Related

Is there a way to chain double try/finally exceptions rather than losing or logging?

If my try throws, and my finally throws, how can I hold onto both exceptions, in a single chain, so that I can let them propagate up the stack naturally instead of requiring an intermediate logging facility?
I thought this might help:
Exception exCause = null;
try {
// do something risky
} catch ( Exception ex ) {
exCause = ex;
throw;
} finally {
//check for an important error condition
// if error: throw new ApplicationException("finally failed", exCause);
}
But I wasn't sure if it might break something in the framework.
Obviously it still has the problem of two pre-existing exceptions that can't be merged if I call something that throws an exception in the finally, but I thought it might help a little bit to alleviate the need for every library in a system to have access to the same tracing routines.
Maybe you could have a look at the System.AggregateException class
AggregateException is used to consolidate multiple failures into a single, throwable exception object.
http://msdn.microsoft.com/en-us/library/system.aggregateexception.aspx
That might help you
This situation is best avoided by writing your finally handler in such a way that it won't throw an exception.
Neither C++, nor Java, nor .Net, has historically offered any good way of dealing with exceptions that occur in stack-unwinding cleanup code. This is unfortunate, because in many cases exceptions which occur in cleanup code are more important to the behavior of the program than exceptions which occur in main-line code, but are less helpful for diagnostic purposes (especially since a clean-up exception may occur as a result of a main-line exception).
It is possible in VB.net to write a try/finally block in such a way that the finally code will know what exception, if any, caused code to leave the try block, without claiming to catch or handle the exception in question. Unfortunately, that isn't possible in C# though it's possible for code in C# to achieve such an effect by calling a wrapper written in vb.net; the use of such a wrapper may be helpful even in vb.net since the code necessary to achieve the proper semantics is a bit icky. The using block in both languages could be improved if it could use an interface something like IDisposableDuringException { void Dispose(Exception ex);} which would be called if the Dispose was being executed during stack unwinding for an exception. That would allow code in the Dispose method to include the supplied exception in any exception that it might throw, and would also for the possibility of having dispose behavior vary based upon whether an exception was thrown (e.g. transaction scopes should clearly perform a rollback if they exit via exception--that's the point of them after all--but requiring them to implicitly perform a rollback when exited via normal means is icky).
With regard to what should happen if an exception is thrown during finally cleanup, I would suggest that whether or not an exception is pending, the proper behavior should be to throw something like a custom CleanupFailureException. Even if the calling code would have been prepared to catch e.g. InvalidOperationException thrown from the main-line, a successful completion of the main-line followed by an InvalidOperationException during cleanup will likely represent a situation different from the one the code was prepared to handle, and should thus use a different exception type.
Incidentally, there's often some debate about whether code should assume unexpected exceptions are fatal or non-fatal. I would posit that in many cases the proper approach would be to have stack unwinding from unexpected exceptions expressly invalidate the objects that were being worked with, such that all future operations with those objects will cause exceptions. This would have the effect that if an unexpected exception may corrupt a critically-important object the program may die off before doing any damage, but simultaneously allow for the possibility that if an exception corrupts an object which isn't going to be needed anyway (e.g. if an unexpected problem occurs while loading a document from a damaged file, and in the attempt to load the document the data structures associated with it got hopelessly corrupted, then if the code can abandon the partially-loaded document proceed sensibly without it, such corruption need not affect anything else.

handling exceptions in .net

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.)

Cost of Custom Exceptions

I've read that throwing exceptions is an expensive operation. However, doesn't creating your own exceptions make your code more expressive and readable?
Some of my coworkers suggest that you should just use System.Exception and insert your custom text into the message instead of creating a new custom exception.
I'm interested in other opinions. Appreciate any suggestions.
Do not throw System.Exception. Ever.
The problem with it resides in the calling code. It is a bad practice to catch the general Exception object for many reasons. If you throw an instance of the Exception base class, then calling code has no choice but to catch Exception if they want to handle it. This forces the calling code to use a bad practice.
Also, the calling code has no reliable means of distinguishing what the exception was, if all it gets is Exception.
It is typically best to use one of the pre-defined exceptions if any are applicable (ArgumentException, InvalidOperationException, etc.). If none correctly describe the situation, then a custom exception class is a perfectly good way to go.
It's the overhead of throwing an exception itself (creating the object, walking the stack, etc.) that's costly. Making your own exception class adds almost no overhead, so if you're going to throw an exception, don't make it new Exception("message")!
Exceptions aren't meant to be read by people (though their messages and stack traces are read by people), they're meant to be read by code. If there's something your code can do in response to a custom exception, by all means go for it. But the exception is just destined to be logged, there's no point to making a custom one.
The overhead of custom exceptions is that they're another thing to maintain and test. If an existing exception is suitable, use that instead. (E.g., ArgumentNullException instead of ZipCodeNullException.)
If there's any reason for your exception to be caught and handled differently from standard Exceptions, then you should create your own class.
If there's any reason for your exception to take different arguments (e.g. to produce a specially-formatted message based on a set of arguments that you're often likely to have), then you should create your own class.
In any other case, you're safe just using Exception. Generally speaking, it doesn't really cost any more to instantiate or throw a custom exception than a standard one, at least not compared with the expense of throwing an exception in the first place. Exceptions, by definition, should be exceptional, and therefore performance during the throwing of an exception is a non-issue. The point is to have all the information you need when the time comes to look at why that exception was thrown.
You should never throw a System.Exception, because then the only way to catch is is by catch(System.Exception). It's very bad practice to catch a blanket exception like that. You should catch specific exceptions, which give you a way to properly handle it without crashing the software. By generating custom exceptions, you give yourself a way to potentially recognize and recover from them.
For example, if your code means to open a file, and you get an unknown exception, how do you recover from it? However, if you catch a specific File Not Found exception, that is much easier to recover from. You can tell the user definitively that the file doesn't exist.
I don't see a reason to believe that custom exceptions are any more expensive than the built-in ones.
"Expensive" is a relative term and - as the name already suggests - an exception should be an exception, so it will probably not affect the performance of your code. The cost of throwing an exception is - as far as I know - independent of the type of the exception, so you should not restrict yourself to System.Exception.
But most important: http://c2.com/cgi/wiki?PrematureOptimization
I prefer to use the most appropriate built in exception, and if that doesn't already exist, derive my own from System.ApplicationException.
I wouldn't recommend throwing System.Exception with a custom message.
Your coworker is talking nonsense. Throwing an exception is the same cost regardless of the class.
And to be honest, all this talk of "expensive" exceptions - yes they are more expensive than a null check or some such, so don't ever use them as a replacement for some sanity check, but they should be encouraged where they make sense (like IOException for example, that's an excellent use case for them - problems with I/O are an exceptional case and they usually must be handled outside of normal program flow).

When to use a user defined Exception and some good examples/best Practices?

I would assume that most User-defined Exceptions are for Business Logic level exceptions, but what are some good reasons to use a User-Defined Exception and what are some good examples?
Is a user-defined exception's only advantage that you can define a consistent Error Message?
What logic can be written inside exceptions to make them truly more useful?
After all, can't you just do this: throw new Exception("Some Error Message");
Having user-defined exceptions is useful because it allows you to handle different kinds of errors in specific ways. Why does .NET define so many different types of exceptions if they could just throw all exceptions as System.Exception with a different text message? The reason that there are different types of exceptions in .NET is that you can catch individual types of errors and handle them differently. That's the same reason you would define your own user exceptions - so that you can provide a different response based on the type of exception that occurred.
You can also create user-defined exceptions that include additional data. For example, you could define a severity level based on an enum, an integer error code or anything else that might be useful to the calling program to identify what went wrong. As for logic to include in exceptions, I generally just try to report what went wrong and leave the logic (what to do about the error) to the calling program. In some cases, I have the exception code automatically write the error to a log file if it has exceeded a certain severity level (e.g. warnings are thrown but only critical errors are written to the log file).
You should create very few user-defined exceptions. They should only be used if someone is going to catch the exception and do something specific with it. If throwing your exception instead of InvalidOperationException is not going to make the code behave differently, then throw InvalidOperationException.
There are quite a lot of Exceptions already in the .NET framework, which you should use if you can find one that could be used for your exceptional circumstance.
For example, in my configuration classes (which are normally wrappers around the ConfigurationManager) I throw ConfigurationErrorsException when ever a value can't be parsed correctly.
When parsing custom values from text or something else that requires a specfic format and the parsing fails, I throw a FormatException
However if my BankAccount object doesn't have enough money in it for me to withdraw £10 then I'll write and throw InsufficentFundsException because then that way I can handle that specific error case, if it ever occurs.
Hope this (somewhat) helps.
No, they are not only for messages. You can look for User defined ones in the exception list of a catch block.
catch(UserDefinedException){}
catch(Exception){}
You can use User Defined Exceptions anytime you want to look for something specific that occurs. Maybe a Client ID is out of a specified range and you want to look for that specifically. Instead of having to parse the error message (which can be a pain, and is prone to errors, like if the message changes later down the road), you have an exception you use and you know that somewhere else in the code is specifically telling you "Hey this happened. You need to be aware of it."
User defined exceptions can be used within a component to allow consumers of the component the ability to catch them with a greater level of granularity then the catch (Exception) block. This will provide the component consumer with the ability to perform different tasks, based on which exception has been thrown. User defined exceptions should only really be created when there is a real expectation that consumers will use them to differentiate in this way.
You can also add properties to store additional meta-data with a user-defined exception, such as an error code (for example when calling an unmanaged API). This is more user-friendly than simply putting stuff into the Data property of the Exception object.

Exception handling using an HttpModule

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.

Categories

Resources