Understanding and Using Exceptions

(this is a really long post…only read it if you (a) don’t know what try/catch is  OR (b) actually write catch(Exception ex)  or catch{ })

The first thing I look for when evaluating someone’s code is a try/catch block. While it isn’t a perfect indicator, exception handling is one of the few things that quickly speak about the quality of code. Within seconds you might discover that the code author doesn’t have a clue what he or she is doing. It may be fun to point and laugh at, but poor exception handling can have a serious impact on the maintainability of a system. Proper exception handling isn’t very difficult, technically there’s nothing to it. It all comes down to grasping the fundamentals.  Too many developers consider exceptions dangerous to the health of a system. If you come from an exception-less language, you might be cursing Microsoft developers for ever having introduced them in the framework.

All exceptions in the .NET framework inherit from the base System.Exception class. This class exposes a handful of members you are likely familiar with, such as StackTrace and Message. Exceptions are raised by the framework, a library you are using or your own code when an exceptional situation occurs. While I don’t often run into over zealous use of exceptions, it is important to understand that they are meant to be used for truly exceptional scenarios. For example, if a user’s registration fails because the email is already in use, throwing an exception might not be appropriate. You’ll often hear people say “only use exceptions in exceptional cases”, as I just did. This is very sound advice when throwing your own exception, but what about catching and handling exceptions? Well the fundamental point to understand is the same, when an exception does get thrown, be aware that something truly exceptional happened.  That might sound a little bit obvious, but a common example will show just how poorly understood the point is:

try
  connection.Open()
  command.ExecuteNonQuery()
catch
  return false
end try

You might have seen, or even written, similar code before. In a previous blog post, I pointed out almost identical code in official Macromedia documentation. There’s actually more than 1 problem in the above code, but let’s focus on the catch block – the place the exception is supposed to get handled. Does anyone see the exception being handled? It isn’t. Instead, we’ve been warned that something truly bad has happened, and swept it under the rug. This is known as exception swallowing, and it’s a sure sign of someone who’s afraid of and doesn’t understand exceptions. If you truly understand that an exception is a sign of an exception situation, you’ll never dare sweep it under the rug!

If you aren’t supposed to swallow them, what’s the game plan going to be? The first thing to realize is that much more often than not, there’s nothing you’ll actually be able to do with exceptions. If I was to guess as to why developers get hung up on exceptions, I’d have to say this is it. For many developers, having an exception bubble up through code, where it’ll eventually cause the application to crash, seems unimaginable. For some reason, these same developers don’t seem to be too worried about not being able to connect to their database – we’ll just return false. The simple truth is that if you can’t actually handle the exception, don’t. We’ll implement logging and friendly error messages much higher up in the code, where it can be globally reused and easily maintained. If the above code makes it to a production server, no error message will be displayed, no meaningful data will be recorded and it might take hours (or days) before you even know something’s wrong.

Rethrownig exceptions
Does that mean that you should never catch exceptions? Not necessarily, but you need to be careful what you do in there. One of the few technical hangups developers have is how to rethrow a caught exception. Since it might not be obvious at first why you’d do that, let’s look at an example. Pretend we’ve build code that allows user’s to register. Our code will first enter the record into the database (assuming all business rules pass), and then send a confirmation email out that details how the account can be activated. If sending out the email fails, we’ll want to remove the record from the database so that the user can try again with the same username/email (else he or she will get an error saying the username or email is already in use). With proper use of exceptions, this is a simple matter to accomplish:

try
{
  Emailer.SendNewUserActivation(this)
}
catch (SmtpException ex)
{
  this.Delete();
 
throw;
}

In the above code we haven’t handle the exception, but we’ve done some important cleaning up. The code can’t go in the finally clause because that’s called on failure AND success (and we don’t want to delete the record if everything was a success).  The real gem in the code is the throw statement. This keeps the exception on the stack, where it’ll bubble upwards. The calling code won’t know that we ever caught the exception and did a bit of internal house-cleaning – which is just what we want because we did nothing to handle the exception.

(in the comments below, Mark Kamoski has some alternative solutions to the code above (along with some concerns) that I think are worthwhile, so scroll down and find his post!)

There are two variations to the code above. Instead of simply using throw; we could actually use throw ex;. The difference between the two, though subtle, it quite important to understand. When you use throw ex; you’ll modify the call stack and make it look like your code was the source of the exception. You are effectively throwing away useful debugging information. As I’ve said before, when you simply throw; it’s as though you didn’t do anything at all! We’ll talk more about throwing your own exceptions in a later post, but if you want to actually be involved in the exception bubbling chain, it’s generally better to throw a new exception and specified the caught exception as the inner exception, such as:

throw new SomeTypeOfException(“User Activation send failed“, ex);

Cleaning up after yourself
If you follow my advice (and I’ll give you a much better source than just my own word soon), you’ll end up with very few Try/Catch statements. Instead what you should be using are Try/Finally statements, or the using statement.  While you might not be able to handle an exception, you can certainly clean up after yourself. Most people know this, but finally happens whether an exception is raised or not, and is pretty much guaranteed to happen – so you can return in your try block and rest easy knowing your finally cleaned up your resources. Here’s an example:

dim connection as new SqlConnection(GET_CONNECTION_STRING_FROM_CONFIG)
dim command as new SqlCommand(connection)
‘…set stuff up
try
  connection.Open()
  ‘might wanna check for DbNull or something
  return cint(command.ExecuteScalar)
finally
 connection.Dipose()
 command.Dispose()
end try

If you instantiate your code inside the try, make sure to check for nothing before disposing:

dim connection as SqlConnection
dim command as SqlCommand
try
  connection = new SqlConnection(GET_CONNECTION_STRING_FROM_CONFIG)
  command = new SqlCommand(conection)
  ‘…set stuff up
  connection.Open()
  ‘might wanna check for DbNull or something
  return cint(command.ExecuteScalar)
finally
 if (not connection is nothing) then
    connection.Dipose()
 end if
 if
(not command is nothing) then
    command.Dispose()
 end if
end try

 
The above code is a little messy, which is exactly why C# and VB.NET (as of 2005) support the using keyword:

using (SqlConnection connection = new SqlConnection(…))
{
  using (SqlCommand command = new SqlCommand(…))
  {
    //..set stuff up
    connection.Open();
    return Int32.Parse(command.ExecuteScalar);
  }
}

I’ve heard some people say they dislike nested using statements, but if you compare the two examples, I think it’s much cleaner, readable and less error prone.

More on actually catching exceptions
Now there are some times when you’ll be able to handle an exception. Everyone knows that you always catch specific exceptions first and work your way towards the base exceptions. You should also, never-ever catch System.Exception. Say we wrote code that took a query string value (or any string for that matter) and tried to turn it into an integer. If it fails, we want to default to a given value. You might write something like:

public static int ParseInt(string value, int defaultValue)
{
 try
 {
  return Int32.Parse(stringValue);
 }
 catch(Exception ex)
 {
  return defaultValue;
 }
}

That’s wrong. What happens if Int32.Parse threw a ThreadAbortException or an OutOfMemoryException, does returning a defaultValue handle those exceptions? No. Instead, you need to catch only the specific exceptions you are handling:

try
{
  return Int32.Parse(stringValue);
}
catch (FormatException ex)
{
 return defaultValue;
}
catch (InvalidCastException ex)
{
 return defaultValue;
}
catch (OverflowException ex)
{
 return defaultValue;
}

Of course, that can be a serious pain to write and maintain. The solution is to apply what we learnt earlier about rethrowing caught exceptions:

try
{
 return Int32.Parse(stringValue);
}
catch (Exception ex)
{
  if (!(ex is FormatException) && !(ex is InvalidCastException) && !(ex is OverflowException))
  {
    throw;
  }
  return defaultValue;
}

While it’s true I said that you should never catch Exception, notice that it’s being rethrown (using throw;) if it isn’t the expected type. This works just as well in VB.NET, or you can even use VB.NET’s when clause.

Global Error Handling
If you’ve made it this far, you might be getting a little panicked. Since we aren’t catching exceptions left and right, they’ll bubble until they crash the system. Well that’s where global exception handling comes in. It lets us write, in a centralized (i.e., easy to change) way, any exception logging we want and how to display the error in a friendly manner. Now I’m getting a little tired of typing, but here’s the httpModule I use to get the job done (notice it relies on log4net to do any logging). If you aren’t familiar with httpModules, and you don’t want to bother learning, you can take the code from application_error and stick it in your global.asax’s application_error.

using System;
using System.Web;
using log4net;

namespace Fuel.Web
{
   public class ErrorModule : IHttpModule
   {
      #region Fields and Properties
      private static readonly ILog logger = LogManager.GetLogger(typeof(ErrorModule));
      #endregion

      #region IHttpModule Members      
      public void Init(HttpApplication application)
      {
         application.Error += new EventHandler(application_Error);  
      }      
      public void Dispose() { }
      #endregion

      public void application_Error(object sender, EventArgs e)
      {
         HttpContext ctx = HttpContext.Current;
         //get the inner most exception
         Exception exception;
         for (exception = ctx.Server.GetLastError(); exception.InnerException != null; exception = exception.InnerException) { }
         if (exception is HttpException && ((HttpException)exception).ErrorCode == 404)
         {
            logger.Warn(“A 404 occurred”, exception);
         }
         else
         {
            logger.Error(“ErrorModule caught an unhandled exception”, exception);
         }
         ctx.Server.ClearError();
         //if you want, you  can simply redirect to a generic “oops, an error occurred page” ala:
         //this is what I recommend until you get into creating your own exceptions
         //Response.Redirect(“error.asx”);

         
      }
   }
}

What if you disagree with me?
You might disagree with what I’ve said. You might even point to this MSDN reference that supposedly tells you how to handle exception: http://msdn2.microsoft.com/en-us/library/24395wz3.aspx.  In it you’ll find very different advice, namely:

“It is preferable to use Try/Catch blocks around any code that is subject to errors rather than rely on a global error handler.”

I’ll counter that crap (and i am trying to get it corrected, because it IS flat out wrong), with a quote from Anders Hejlberg (you know, the lead architect for C#, one of few Microsoft distinguished engineers, the inventor of TurboPascal and a lot more):

“No, because in a lot of cases, people don’t care. They’re not going to handle any of these exceptions. There’s a bottom level exception handler around their message loop. That handler is just going to bring up a dialog that says what went wrong and continue. The programmers protect their code by writing try finally’s everywhere, so they’ll back out correctly if an exception occurs, but they’re not actually interested in handling the exceptions.

The throws clause, at least the way it’s implemented in Java, doesn’t necessarily force you to handle the exceptions, but if you don’t handle them, it forces you to acknowledge precisely which exceptions might pass through. It requires you to either catch declared exceptions or put them in your own throws clause. To work around this requirement, people do ridiculous things. For example, they decorate every method with, “throws Exception.” That just completely defeats the feature, and you just made the programmer write more gobbledy gunk. That doesn’t help anybody.

It is funny how people think that the important thing about exceptions is handling them. That is not the important thing about exceptions. In a well-written application there’s a ratio of ten to one, in my opinion, of try finally to try catch. Or in C#, using statements, which are like try finally.

In the finally, you protect yourself against the exceptions, but you don’t actually handle them. Error handling you put somewhere else. Surely in any kind of event-driven application like any kind of modern UI, you typically put an exception handler around your main message pump, and you just handle exceptions as they fall out that way. But you make sure you protect yourself all the way out by deallocating any resources you’ve grabbed, and so forth. You clean up after yourself, so you’re always in a consistent state. You don’t want a program where in 100 different places you handle exceptions and pop up error dialogs. What if you want to change the way you put up that dialog box? That’s just terrible. The exception handling should be centralized, and you should just protect yourself as the exceptions propagate out to the handle.”

(you can read the entire interview here, very good read, especially if you come from a Java backgorund)

Make sure to read that and understand that well, because it’s all amazing advice and the real foundation of what you need to know with respect to exception handling.

In Closing:
Here are the key points:
- Don’t catch exceptions unless you can actually handle them
- Do know how to rethrow exceptions properly
- Do use using or try/finally often
- Don’t swallow exceptions
- Do use a global handler to help you log and display a friendly error message

I did want to talk about creating your own exceptions, but I think I’ll save that for another post.

This entry was posted in Grab a coffee before reading. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

45 Responses to Understanding and Using Exceptions

  1. Krispy says:

    For info, console apps & Windows Form apps camn use the follwoing snippets to capture any unhandled exceptions…

    //GUI Apps
    Application.ThreadException += new ThreadExceptionEventHandler(UnhandledExceptionHandler);

    //Console Apps
    Thread.GetDomain().UnhandledException += new UnhandledExceptionEventHandler(Program_UnhandledException);

    This will give you a central location for capturing unhandled exceptions and an opportunity to display a user friendly message highlighting the error. It will also remove the need to wrap every method/event with a try/catch block.

  2. Rainer says:

    Use

    if (ex is HttpException && ((HttpException)ex).GetHttpCode() == 404)

    instead of

    if (exception is HttpException && ((HttpException)exception).ErrorCode == 404)

  3. Nice post on using Exceptions… thank you

  4. Tan Pho Han says:

    So what should I do when I’m validation user inputs or business rules?

  5. Hey Karl,

    This is the first page I’ve read on exception handling that suggests that try/finally out to be used much more that try/catch. I often get annoyed by all the try/catch nonsense I see in code. Even more annoying is when exceptions get converted into return values which have to be checked by the calling routine.

    The purpose of structured exception handling is to eliminate the type of control coupling that occurs when error codes are passed up through calling methods by means of a return value or a parameter until a method is reached that can handle the error. When errors are handled in this way, each method in the call stack has to implement code to check the error code and decide what to do. The decision is generally to suspend whatever the routine is doing and pass an error code up to the next level until a level is reached that handles the error. Structured error handling eliminates the need for all this error handling code between the level where the error occurred and where it is handled.

    Programmers that are unaware of the intent of structured error handling will often write code to catch exceptions within each routine, convert the exceptions into error codes, and then pass the error codes up to the calling routine through a return value or parameter. Handling exceptions like that is kind of like using goto statements when you could be using if-then-else or some other structured programming construct. Don’t convert exceptions to error codes unless some interface requires it.

    And in regard to Woodward question about what to do with an exception — why not also log it in a bug tracking system?

    See Using PR-Tracker to Collect Exception Data

  6. E-Doctor says:

    Hi Karl, i am developing a win form application, and i have a try-cath code, and the “FIRST TIME” an error occurs in the try block, about “6-8 SECONDS” i have to wait until the code reach the catch block (I know it because i place in the catch block a “messagebox.show(ex.ToString());” ). Then, subsequents errors in that try block, it’s really fast to get to the catch block (maybe milliseconds) . To repeat the scenario, i have to close the application, and reopen it. I even catch NOT the general Exception class, but the specific exception, in my case, the System.FormatException.

    “WHY the first time is too long time to reach to the catch block?”

  7. karl says:

    shaheen:
    If you throw an exception knowing that you’ll always catch it, it might be not be a good use for an exception.

    If you’re describing a “marker” exception, where you just need a “custom” exception so that you can catch something explicitly without swallowing Exception, then I think you’re on the right direction. I realize it seems like pointless code, but it can be pretty handy.

  8. shaheen says:

    I like this post . It is very essential. But still I’ve some confusion. suppose I build a custom exception derived from (Exception, not used ApplicationException) and want it to catch in try catch block. But it can’t catch the exception untill I throw it explicitly. the custom exception is not actually a custom exception, I just give a different name to a known exception. Am I in a right direction?

  9. Neil says:

    Excellent and very helpful article. I look forward to the follow up on creating own exceptions and seeing what you have to say about that.

    I’d also recommend to anyone interested in this to http://research.microsoft.com/specsharp/papers/krml135.pdf

  10. karl says:

    Jason, I don’t think you went far enough…I think you should hook into the HttpModule’s OnError event….why rewrite the same code for every single one of your pages? (alternatively, you could create a base class that all your pages inherit from).

    This post has gotten a lot of comments, and while there’s some differing of opinion, I think most would agree that your lead is likely wrong.

  11. Jason says:

    I’ve just been going round and round with my team lead about exception handling. I haven’t done a lot of it in my time as a developer, so I really didn’t understand it all that well. I wrote a single method on each of my pages that received a string to represent the method name, and an exception. It would log the error and then hide certain elements on the page and display an error label. My team lead didn’t like this approach because it allowed processing to continue even after an exception occurred. He asked me to rewrite the code. So I hopped online to see what I could learn about exception handling and I stumbled across Page.Error event and I implemented added the event handler to one of my pages, removed all try/catch code that I’d had in there. I added code to generate some exceptions in the business layer, in some web controls and on the page itself in various events. The error handler event caught every single one of these errors, so I went ahead and added the event handler to all of my pages, and I then logged the event and redirected the user to an error page. I added specific try/catch blocks in the areas where I wanted to actually do something with the exception, but other than that, I left no try/catch blocks at all. This seems to work very well, but my team lead doesn’t like it. He wants me to add the try/catch blocks because that’s what everyone else is doing. I’m going to do what he asks, because, well, you know, he IS the lead, but inside I think this is a step backwards. Am I wrong?

    Thanks!

  12. Anon says:

    HEALTH WARNING: Unfortunately this posting contains a serious error which perpetuates the confusion that 95% of developers have about what exceptions are.

    < <
    it is important to understand that they are meant to be used for truly exceptional scenarios. For example, if a user's registration fails because the email is already in use, throwing an exception might not be appropriate. You'll often hear people say "only use exceptions in exceptional cases", as I just did. This is very sound advice when throwing your own exception
    >>

    This is utterly mistaken. Like many developers, the author has been misled by (1) the term “exception” and (2) the much-discussed performance considerations of throwing an exception.

    The author thinks that an exception is something “exceptional”; something to do with the *frequency* with which a condition occurs.

    Please don’t perpetuate this misunderstanding. Exceptions are used to represent *method failure*. Imagine a method designed to perform a task, let’s say XYZ, named

    DoXyz()

    If for *any* reason, the method couldn’t do what it says it will do, it will throw an exception. That’s what exceptions are – they represent a failure of a method to adhere to its contract; i.e. that it couldn’t do *what it says* in its name.

    Look at every method in the .NET framework. It will either work, or it will throw an exception.

    If this basic idea is not understood, it is impossible to write your own code that correctly throws exceptions, correctly catches exceptions, and much less write an article called “Understanding and Using Exceptions”.

  13. karl says:

    Paul:
    That really does sound like a nightmare. To be honest, I don’t have any good suggestions for tracking local variables and the like but….

    Why do you need local variables? If this is a web app, a stack trace and a dump of the request object (raw http, or querystring or form) should let you repro the bug easily.

    Out of curiosity, how useful have you found all the extra hoops and jumps when a bug actually did arise?

  14. Paul says:

    I’ve gotten into what’s probably a really bad habit, of try/catching rethrowing everywhere for the purpose of recording as much information about the errors as possible. I started out trying to address the issue of being able to get the methods parameters and values for those paremters, along with the values of any other pertinent local variables in those methods, and log them to my error log. So with that, we ended up try/catching/rethrowing in every routine, and to avoid logging the same error as it bubbles up, we’d create a new exception that once bubbled up, if caught, we knew not to log it since if it was of that type, we knew it had been logged. Any suggestions on how to log all of the additional data that I mentioned, and use a cleaner method for exception handling?

  15. floid says:

    about the db conect example:
    in fact returning false is precisely the correct thing to do:
    you couldnt connect

    (of course,there migh be some cleanup needed before returning false)

    now the problem with the example code you show is not that it doesnt ‘handle’ exceptions,
    but that the granualrity might be wrong; as shown there is no distinction between the connection attemp and the query

    but the real point is that there is a pathological exception idiom baked into .net
    which needs to be corrected by judicious wrapper code

    people are very confused about this

    what is ‘handle’ anyway?
    what is ‘excpetional’? what is ‘normal’?

    if dpending on the subjective views of developers, these questions have no consistent answer

    it helps to look at the roots of the mechanism: the current syntactical support of exception handling is a more orderly setjump/longjump which can unwind the stack,
    but the original problem scope was for seriously broken situations,
    such as out of memory, disk full, etc,
    situations which cannot be handled programmatically, because
    the programming model is broken

    but now, due to the design mistakes in the clr and ms libraries, augmeented by design mistakes by 3rd party libarries,
    execption mis-use is widespread

    so, while well intentioned, this blog, as well as msdn, are both wrong

    the only correct way to handle exceptions is to wrap the pathological exceptions and return meaningful results; this of course depends on something else which is in short supply: sound design.

    the very very few real and actual exception conditions can be propigated, because, as if there’s nothing that can be done about it, there’s nothing to do

  16. Narges says:

    Hi Karl,
    thanks for your Great post. it helped me a lot :)

    can you help me for a few exceptions that is better to be caught in data layer? for example connectionException.

    and what about informative data that can be added to a custom exception that is defined as DALException, what can be them?

    in a better word, what can be the properties which is defined for DALException which filled when we want wrap a concrete exception in data layer with DALException.

    thanks in advance.

  17. Martin Smith says:

    Some people might find this heretical and I see the points you’re making but I still find catch{} useful.

    For example if in my App I would like to clean up a file if possible but am not particularly bothered if it stays there or not I will use a function like this.

    public static void TryAndDeleteFileMaskingAllErrors(string filePath)
    {
    try
    {
    File.Delete(filePath);
    }
    catch { }
    }

    That saves me the bother of having to write specific code to handle all 7 errors that the Delete function might return.

    If indeed these other Out of Memory type exceptions etc. occur then they will likely occur again outside of this function and will be caught by the global error handler then

  18. Senthilkumar says:

    This Article is good

  19. SenthilKumar says:

    Good

  20. Senthil says:

    None

  21. karl says:

    methusaleh, thanks for the more insightful opinion – the first one left a little to be desired (imho), but you more than made up for it :)

    I haven’t spent any significant amount of time in Java, so I can’t contribute much to the high-profile discussion around checked exceptions or not. In my limited experience, I have seen the behavior Anders is talking about – too many exceptions to catch so simply swallowing them all. He is correct, when handled this way, it’s counter productive. I haven’t seen a medium or large Java project (in terms of complexity), properly implement exception handling (not because they don’t exist, simply because I’m not exposed to that type of Java codebase). It would be quite interesting to see and I’d probably learn a thing or two.

    I can’t help but wonder out loud if Anders view isn’t more realistic (perhaps sadly so, and yes perhaps Microsoft should be doing more to set the bar higher).

  22. Methusaleh says:

    Karl, in response to your question:

    The article infers that checked-exceptions are an anti-pattern based on actual usage by developers, and by the issues it causes for versioning. Yet without checked-exceptions how can a developer guarantee correct method behaviour as defined by its contract when it is unable to ask the same of any librarys or APIs it itself uses?

    Thus programming is now dumber because of a decision that was made based on dumb developers. He should have based his decision on the correct usage of checked-exceptions rather than on bad usage. Maybe if Anders had read http://thedailywtf.com/ he might have just concluded that developers should be stopped from developing altogether.

    Some comments on the article:

    Anders Hejlsberg, “In version two of foo, I want to add a bunch of features, and now foo might throw exception D. It is a breaking change for me to add D to the throws clause of that method, because existing caller of that method will almost certainly not handle that exception.”

    The same can be said of changes to method signatures. Its called breaking the contract.
    The point is that thrown exceptions are part of an interface’s defined contract. This should be obvious because exception throwing is application behaviour.

    Bill Venners: “But aren’t you breaking their code in that case anyway, even in a language without checked exceptions? If the new version of foo is going to throw a new exception that clients should think about handling, isn’t their code broken just by the fact that they didn’t expect that exception when they wrote the code?

    Anders Hejlsberg, “There’s a bottom level exception handler around their message loop. That handler is just going to bring up a dialog that says what went wrong and continue. The programmers protect their code by writing try finally’s everywhere, so they’ll back out correctly if an exception occurs.” etc.

    He later goes on, “In the finally, you protect yourself against the exceptions”

    I would certainly hope that the developers are checking what exceptions are thrown. Is it safe for the application to continue? Should the application terminate immediately? Should the developer save a possibly corrupt document or not?! How do you handle this in a finally clause.

    How many subsytems are the exceptions propogating through? How many exceptions are possibly going to be thrown? I really like that I have read documentation to know what exceptions I have to handle and possibly recover from. God I hope the documentation written by ACME-Corp is correct or the first time I see one of these exceptions might be in production. You hope to God this application isn’t controlling an X-Ray machine.

    Anders Hejlsberg, “And once you aggregate that with another subsystem you’ve got 80 exceptions in your throws clause. It just balloons out of control.”

    Quoting from “Richard A. Demers – Subsystem Exception Handling in Smalltalk”
    http://www.whysmalltalk.com/articles/demers/subsystemexception.htm

    1. A public method of a subsystem should only raise only those exceptions that it explicitly defines in its interface.
    2. Further, a subsystem should trap and handle all other exceptions raised by its own objects and by any subsystems it uses.

    So under C# we have 80 exceptions bubbling out with no way of knowing which ones to expect.

    He finishes with, “In the large, checked exceptions become such an irritation that people completely circumvent the feature. They either say, “throws Exception,” everywhere; or—and I can’t tell you how many times I’ve seen this—they say, “try, da da da da da, catch curly curly.” They think, “Oh I’ll come back and deal with these empty catch clauses later,” and then of course they never do. In those situations, checked exceptions have actually degraded the quality of the system in the large.”

    QED.

    In your article you have covered areas of exception management, logging and instrumentation that we do agree on. My comment is solely based on the Artima article. While I agree with Anders concern, there is so much more that Microsoft could have done. While checked-exceptions (and exceptions in general) are not perfect, C# is worse for not having them.

  23. karl says:

    Mark:
    Very good points and two alternative solutions certainly worthwhile. I’m not sure than any one solution is flat-out better than the others, now that you mention it though the conditional state is probably how I’d do it :)

    I’ve updated the post and made a reference to your comment for my information.

    As for the transaction option, the way I’m seeing it, it would require more interaction between my data layer and business layer than I feel comfortable with (in this particular case). Though it could certainly be a good solution in other cases or with a different architecture.

  24. Mark Kamoski says:

    First, this is a good article and I thank you for it.

    Second, I want to “take exception” with something that you said.

    (Actually I should say “comment on” instead of “take exception”, but I simply could not resist the pun.)

    Anyway…

    You say “Pretend we’ve build code that allows user’s to register. Our code will first enter the record into the database (assuming all business rules pass), and then send a confirmation email out that details how the account can be activated. If sending out the email fails, we’ll want to remove the record from the database…”.

    The code you gave is this…

    try
    {
    Emailer.SendNewUserActivation(this)
    }
    catch (SmtpException ex)
    {
    this.Delete();
    throw;
    }

    try
    {
    Emailer.SendNewUserActivation(this)
    }
    catch (SmtpException ex)
    {
    this.Delete();
    throw;
    }

    …so I am wondering?

    Why isn’t the insert transactional and simply rolled back if the email send fails?

    Sure, this keeps the connection/transaction open for longer than ideal; but, the concern that I have is doing TOO much in the catch block. We don’t know what this.Delete() does; but, it shouldn’t do too much, I hope.

    Another strategy is to insert the record in a conditional state. The row is tagged with “isConfirmed” or “isConfirmationEmailSent” or something like that. If that flag is not set, then the record is “dead” after some kind of time out. Sure, this adds overhead and bookkeeping; but, I still don’t like the alternative of putting this.Delete() in the catch block.

    In general, my point would be that one ought to be cautious about type of code is in the catch block. It should be VERY stable and bullet-proof code (if possible). Otherwise, one ought to use a workflow manager that handles such interdependent workflows and the state of the data in general.

    What would you respond to such comments and concerns?

    Please advise.

    Thank you.

    –Mark Kamoski

  25. Dave says:

    Good article but you have a small typo in the section entitled “Rethrownig exceptions” Guess the exception handlers cannot handle spelling ;)

  26. Stanley says:

    Nice article Karl. stej, it is my experience that you do not handle system.exception within your class. Handle the specific errors such as the ones you find in the docs. Leave the system.exception to the global handler because there is nothing you can really do about it at run time. Log it and fix it later. It may end up being something you can catch in your code, but until you can document it with the logs, there is not much you can do.

  27. stej says:

    >> “You should also, never-ever catch System.Exception.”

    I agree, but I think it’s not that easy. It happened to me many times that I wanted to catch only some exceptions (access denied, io error etc.). So I had a look into documentation and listed the wanted ones. So far ok. Anyway, when running the code an unexpected exception was thrown, but I didn’t catch it because I didn’t expect it – it wasn’t in the documentation.

    Then the only solution is to catch System.Exception. Or better exceptions that inherit from it and might be thrown?

  28. karl says:

    I’d like to know where, in that interview, you think that’s being said. What is it you don’t agree with? Do you think my (and his) advice on exception handling is wrong? Should such broad recommendations not be made without disclaimers? What’s the problem?

  29. methusaleh says:

    Anders Hejlberg is wrong. The point he makes is ‘programmers are dumb; lets make everything else dumb to match’ – That’s just brilliant. Good work MS.

  30. tod says:

    Very good post Karl! Having a little over a year of .NET experience, this is one area in particular that I’m working on right now. Your explanation was very helpful, in fact I’m del.icio.us’ing it right now for future reference.

    The funny thing [to me at least] is that just yesterday my mentor was explaining the using statement to me…and then this morning your post showed up in my feed reader. Great timing! :)

  31. Peacedog says:

    Fair point on the swallowing (and no, it didn’t sound “purish/snobbish”) – I was perhaps being too conversational in what I was saying. I had previously been swallowing all exceptions but I’m starting to change that.

  32. karl says:

    John:
    Whether it’s a web app or a desktop one, it’s the same process. Remember, when an exception is thrown in asp.net and you redirect to the error page, you are effectively killing the thread. if the user browses back and tries again (or something else), it’s effectively like them restarting the application.

    That said, for the cases we are talking about here, the exceptions are really unexpected. It’s generally good to display log the error and try to display a friendly error message (I say try because the stability of the system might not be very good (this is where exception swallowing’s actually allowed)). Unless the audience of your application is very technical, I don’t generally feel good about displaying a very detailed message – assuming you have good logging in place that goes beyond “can you tell me what error you saw” over the telephone.

    When I cover throwing your own custom exceptions, it might become a little easier to write slightly more specific error messages that are just as friendly. Additionally, it might become easier to figure out how to actually handle an exception (if not when it happens, perhaps in the global handler). In this case, you might have good choices other than shutting down. For example, you might throw an MyApplicationConnectionFailed exception and decide to ask the user to pick their database again – just to make sure.

    Karl

  33. karl says:

    Rodel:

    Hopefully someone else might step up and give you a more definitive answer, but I’m almost certain that it’s the stacktrace that’s the slowdown. I was curious about this not too long ago, and stumbled accross this newsgroup post, which is quite detailed.

  34. John Woodard says:

    Help me out here, because I’m trying to get my arms around this.

    In the global exception handler, if we’re talking about an application and not an ASP.NET page, what should the handler do other than log the exception? Should it:

    1. Report it to the user?
    2. Close the application?
    3. All of the above?
    4. Some of each, and if so how do you know?

  35. Great porst carl! Just want to have some clarifications.

    We all know that throwing exceptions is slow but I want to know what makes it slow? Is it true that when an exception was encountered it spans another thread? Internally, what makes it slow really?

    thanks!

  36. johnpapa says:

    Great post Karl! To may times I see exception handing logic swallowing up exceptions … and it later bites them.

    I LOVE “using” statements. I have no problem nesting them either … I think it actually helps clarity.

  37. WhoDaPimp says:

    All I gotta say is AMEN!! Great post.
    Like they say, If you dont get it, you dont get it.

  38. Philip Rieck says:

    No disagreement here. A quick personal note, though..

    1) In c#, I really like breaking with my own guidelines on blocks, and “nesting” using statements this way:

    using( SqlConnection conn = …)
    using( SqlCommand cmd = …)
    {
    //Code goes here
    }

    While I (personally) hate blocks without {}, (like naked ifs), this is one place I like the usage.

  39. ewise says:

    The common thing I see from .NET newbies and try-catch other than overzealous wrapping without handling is the throwing of exceptions for user input validations.

    Lucky for us TryParse came along and hopefully with proper community support will beat a lot of those exceptions out.

  40. Marc Brooks says:

    I’ve got your back on this one! Check out my guidelines:

    http://musingmarc.blogspot.com/2005/09/exception-handling-in-net-some-general.html

    More interesting thoughts about when to throw exceptions here:

    http://musingmarc.blogspot.com/2005/10/validation-and-exceptions.html

    And last but not least, a pattern I stumbled on for handling initialization failures in singletons:

    http://musingmarc.blogspot.com/2005/11/pattern-for-rethrowing-exceptions.html

  41. David Hayden says:

    Peacedog – Throwing exceptions is extremely important whenever the client of your class, method, library, or whatever violates the interface contract ( e.g. uses it incorrectly, doesn’t supply correct or enough information, etc.). The key is to throw these exceptions when necessary and immediately upon violation so that bad / unpredictable code never makes it into production.

    Having exceptions being thrown in your application is expensive in terms of performance, which is why by the time your code makes it into a production environment, expected exceptions shouldn’t be occuring. By production time, an exception should be indeed an exceptional event and just logged in a global error handler to be reviewed and fixed.

    Karl’s point is that since the exceptions in a production environment are indeed exceptional and unexpected, you probably will have no clue how to handle them. Most of the time you will just have a try/finally block with the absence of a catch block. Let the exceptions happen and get logged. Don’t swallow them, because you will never know they exist and your application will perhaps run unpredictably and cause more problems than if you were to let the exception occur.

  42. sahilmalik says:

    I like this post +1.

  43. karl says:

    I believe the peformance hit everyone always talks about is in the creation of the exception, not the throwing of it.

    I didn’t cover when/how to create your own exception class and when you should raise your own exceptions. Most of the time I raise an exception when something really bad happened. For example “Hey moron, I need a connection string in the web.config to work properly”. The site won’t work without this key configuration, so spending a couple milliseconds here and there to throw the exception is well worth it (not like the cpu will be doing anything else).

    As I said, over zealous use of exception throwing isn’t something I’ve seen often, so anyone worried about the performance of exceptions probably just doesn’t get it.

    I know this sounds a little purist/snobish, but you can’t really “swallow too much”. You either do or you don’t. I say that because there’s really never a good reason to do it. The two exception are (a) if you rethrow it (which isn’t really swallowing at all), or (b) you are in a global exception handler and want to protect against an endless loop.

    I’m afraid people will read this post and say it isn’t pratical. But it’s really how you should be building real-world applications. What isn’t practical is the mess you’ll end up with if you don’t follow Hejlsberg’s advice ;)

  44. Peacedog says:

    Just the other day I was reading somewhere (forgive me but I can’t find the exact link right now ) about the evils of throwing exceptions, since it generates overhead. Care to comment on that?

    I’m something of a neophyte still (a year and a half out of school; my education was primarily a mix of VB and VB.net, I didn’t start with C# until I came to my current employer). I have been aware for some time that I’m likely doing myself a disservice with too much swalloing. I’ve decided more recently that most of my use of try/catch is unwieldy in general (I amost always use try/catch/finally though).

    And I only recently discovered that using was for more than just importing namespaces.