Click here to Skip to main content
Click here to Skip to main content

Common mistakes when working with exceptions

By , 30 Nov 2010
 

Rethrowing and Destroying the stacktrace

This is an evil one. Because it’s really easy to use it and the compiler does not complain about it (it should be easy to spot by the compiler). The code also looks correct if you don’t know what it really does.

What am I talking about?

try
{
    FutileAttemptToResist();
}
catch (BorgException err)
{
    _myDearLog.Error("I'm in da cube! Ohh no!", err);
    throw err;
}

Looks about right? The problem is the throw err; part. It will wipe the stack trace and create a new one from your catch block. You’ll never know where the exception originated from. Just use throw;

Using Policies for Exception Handling

I’ve started to write several pieces about why you should not use policies (for instance Exception Handling Block in Enterprise library), but I never got really satisfied with it.

The problem with the block is that the examples are still not very good and really tricks you into bad practices.

Anyway, introducing policies can be good if you are following my guidelines in the post “Do NOT catch that exception!”. The problem though is that it’s easy to start adding try/catch/policy everywhere and hence producing unreadable code that is logging the exception multiple times again.

Just handle those exceptions that you can handle. No need for a policy.

Not Including Original Exception When Wrapping

Another common mistake is to not include the original exception when throwing another one. By failing to do so, you are also failing to give information about where the error really happened.

try
{
    GreaseTinMan();
}
catch (InvalidOperationException err)
{
    throw new TooScaredLion
   ("The Lion was not in the m00d", err); //<---- original exception is included, hooray!
}

Not Providing Context Information

This one is actually a golden rule at Microsoft. They really love to give us developers a challenge when something fails. They have built a superior framework with .NET and they need to put us developers back to earth sometimes. Hence the crappy exception descriptions.

This is what I’m talking about:

try
{
   socket.Connect("somethingawful.com", 80);
}
catch (SocketException err)
{
    throw new InvalidOperationException
    ("Socket failed", err);  //I LOVE InvalidOperationException. Read my previous post.
}

What’s wrong? The exception message is just stating the obvious. We already know that the connect fails. But we do not know what it tried to connect to. Always provide contextual information. NHibernate is the glorious king when it comes to developer friendly exceptions. Examine its source code and learn something.

What you really should do is something like this:

void IncreaseStatusForUser(int userId, int newStatus)
{
    try
    {
         var user  = _repository.Get(userId);
         if (user == null)
             throw new UpdateException(string.Format("Failed to find user #{0} 
		when trying to increase status to {1}", userId, newStatus));

         user.Status = newStatus;
         _repository.Save(user);
    }
    catch (DataSourceException err)
    {
        var errMsg = string.Format("Failed to find modify user #{0} 
		when trying to increase status to {1}", userId, newStatus);
        throw new UpdateException(errMsg, err);
    }

I always try to include as much information as possible in my exceptions. One could discuss if that sensitive information should not be included in exceptions. But I say YES! It’s really up to code that EXPOSES the exception (for instance, a logger or a message box) to hide sensitive information. For instance, only log exceptions in a log that the correct people have access to. Exceptions should be dealt with ASAP anyway.

I would never expose an exception to an end user. What use do they have of the exception information? You got a widely used application and need to get exception information? Encrypt it and upload it to your server (with permission from your user of course).

Share and Enjoy:PrintDiggStumbleUpondel.icio.usFacebookYahoo! BuzzTwitterGoogle BookmarksDZoneLinkedInSlashdotTechnorati

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)

About the Author

jgauffin
Founder Gauffin Interactive AB
Sweden Sweden
Member
Freelance developer/architect with a passion for code quality, architecture, refactoring, networking and threading.
 
Solid skills in .NET/C#/MVC3
 
Blog: http://blog.gauffin.org

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralhelpfullmemberPranay Rana18 Dec '10 - 19:47 
helpfull
For any question : http://pranayamr.blogspot.com/
 
vote my article :

Learn SQL to LINQ ( Visual Representation )


Calling WCF Services using jQuery

GeneralDon't forget...memberRichard Deeming10 Dec '10 - 8:32 
... never use throw new Exception(...), always use a more specific exception type.
 
This should be rule #1 on any list of rules for working with exceptions. I wish Microsoft had made the Exception class abstract; then we wouldn't have to deal with stupid code like this[^].



"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer


GeneralusefulmemberCIDev1 Dec '10 - 4:35 
A clearly written and useful article on a topic where far too many programmers make mistakes.
Just because the code works, it doesn't mean that it is good code.

GeneralWhat's important in an exception classmembersupercat930 Nov '10 - 5:33 
It seems that a major feature of a good exception hierarchy is that exceptions should be grouped not based upon what happened, but rather upon what they imply. One can't really do much about the exceptions that will be thrown by the Framework, but for one's own exceptions it may be helpful to have separate hierarchies for exceptions which indicate that the requested operation didn't succeed, but things are otherwise fine, as distinct from exceptions that indicate a fundamental problem. To put it another way, one should organize exceptions such that one branch of the exception tree would be things one would expect a "Try" method to swallow, and another would be things that one would expect to escape from a "Try".
 
Some programs catch exceptions over-eagerly, while others are overly reluctant to throw them. I suspect both such tendencies stem from a common failure to organize exceptions by what they mean, thus leading some people to catch exceptions over-eagerly, to avoid letting an exception slip that they should have caught, while others are reluctant to throw exceptions for anything less than the CPU catching fire, for fear that the caller might fail to catch them.
 
Too bad there's no way to fix the Framework exception hierarchy. At least custom exceptions can be arranged a bit better, and one can try to wrap the standard ones in custom ones when practical.
GeneralThanksmemberJason Ti29 Nov '10 - 0:47 
I read many articles regarding exceptions and u provided something new, 4-rd example is really usefull, nice catch.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 30 Nov 2010
Article Copyright 2010 by jgauffin
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid