Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

Proper exception handling

I’m going to throw my two cents into the exception discussion that Brendan brought up. I believe Jeffrey Richter’s approach is the best, which I learned in person at Devscovery (the “low level” sessions like this were the best ones in the conference). The East Bay IT Group (ebig) has a great overview of Jeff’s exception talk, shown here in part:



“Jeffrey began his talk by defining an exception as an event that occurs when an implicit assumption is violated, and not as many people erroneously believe, simply a rarely occurring event. When an implicit assumption is violated, an exception event should be generated rather than having the function return an error code. Jeffrey gave a great example of how the legacy tradition of returning a -1 for a file read function at the end of a file is actually improper and how it can cause coding difficulties and application errors.

Richter presented an impressive list of the benefits of exception handling. By using more robust, maintainable object oriented code, the result is cleaner, uncluttered centralized program logic. One of the unexpected benefits of exception handling is better performance because many errors can be processed centrally instead of after each function call. Although some early implementations of exception handling using C++ had poor performance, the efficiency of Microsoft’s .NET garbage collector has all but eliminated these problems.

Jeffrey ended his talk with guidelines and best practices for exception handling including liberal use of finally blocks, catching specific exceptions (only lazy developers catch all), graceful recovery design pattern, and backing out but not swallowing of exceptions.

In his presentation on exception handling, Jeffrey did more than describe the rules and show code examples for exception handling on .NET (which, of course, he did exceptionally well). He described a common sense way of looking at exceptions that everyone in the audience could understand. Jeffrey said that an exception occurs when an implicit assumption is violated, and not, as many people erroneously believe, when a rare event has occurred. Richter ended his talk on a positive note, demonstrating that proper handling of exceptions produces cleaner, less cluttered code that is easy to understand and is highly performant.” [ebig newsletter]

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

15 Responses to Proper exception handling

  1. Rudolf's blog says:
  2. Jiho Han says:

    Darrell,

    I wanted to chat with you some time if you don’t mind that is… Do you have an AIM or MSN?

  3. Darrell says:

    Any time. :)

  4. Jiho Han says:

    Excellent. That sounds well, sound. I do remember seeing that vertical rectangle in the diagram.

    Thanks for your advice!

  5. Darrell says:

    Jiho – I would place the ConcurrencyException in a "common" assembly that is accessible to all layers. If you look at the Microsoft .NET Application Architecture guidance, you’ll see they group things like security, logging, exception management as vertical rectangles that "cut across" the horizontal layers of the application. Obviously any application-specific exceptions would only be found in the data layer.

    I would have a generic DataException supertype (this is similar to one of Martin Fowler’s PofEAA patterns) that everything app-specific and data-layer specific would inherit from. Then wrap the original exception so as not to lose the info! And that generic DataException may or may not bubble up to the presentation, depending on whether the domain layer can do anything with it.

    That’s worked very well for us so far.

  6. Jiho Han says:

    Darrell, I agree. But would you consider your generic ConcurrencyException to be part of the DAL or BLL? Also, taking one step further, would you wrap some(or all) of the DataException derivatives into another generic *Exception(or maybe the DataException itself) bubble up to the presentation layer?

  7. Darrell says:

    For DBConcurrency, I would wrap at the database layer and throw a generic Concurrency exception (with the DBConcurrency exception as the inner). The domain layer, or business services layer, or whatever you want to call it, should not know about "DBConcurrencyException". What if you swapped out the database for XML storage? In my opinion, I would then let the generic Concurrency exception bubble up, with maybe the presentation layer making it pretty. :) But that’s just my 2 cents.

  8. Jiho Han says:

    This may be slightly off topic from what you guys are discussing but nevertheless it’s about proper exception handling.

    If you had a concurrency error occur – DBConcurrencyException, for example – while updating a row in the database, how would you propagate this up the tiers? What I mean is which layer(DAL, BLL, UIP or UI) should ultimately *handle* it? Should each layer wrap the exception until it gets to the UI so that it handles the wrapped exception by popping up its own messagebox? Or should, say, a DBConcurrencyException, be left to propagate all the way up to the UI?

    How would you handle it?

  9. Steve Hebert says:

    That would really simplify Maine’s code immensely to:

    AssertException( !appOnFire, Fatal error: application on fire.” );

    AllIsGood();

  10. Steve Hebert says:

    Why not have a AssertException() that compiles to an assert in debug mode and an exception in release mode?

    AssertException(boolean-condition, string);

    On debug it compiles to Debug.Assert( boolean-condition, string)

    On release it compiles to

    if( boolean-condition == false ) throw new AssertionException( string );

  11. Darrell says:

    Yeah, Steve Maine’s a pretty smart guy (big understatement).

  12. Steve Hebert says:

    Interesting. So I would assert first, throw exception second. And only assert on "impossible conditions", because I’ll ultimately want to check exception handling cases in test code and running the app. Cool. Hadn’t thought of it that way.

  13. Darrell says:

    I would think so. Also see Steve Maine’s take on this same issue here (with code sample!):

    http://hyperthink.net/blog/CommentView,guid,3c8d287c-b646-4048-8c9b-b72ed03664b1.aspx

  14. Steve Hebert says:

    Interesting, I didn’t realize the performance issue was a non-factor. Am I misreading it or is he advocating using exceptions the same way we use asserts? Would he go so far as saying "whereever you have an assert, throw an exception"?

  15. Brendan Tompkins says:

    Darrel, like almost everything, I’m sure volumes could be written on this subject.. But, I’ve responded to your post here:

    http://dotnetjunkies.com/WebLog/bsblog/archive/2004/08/25/23240.aspx#23257

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>