none
New Exception Handling Idiom: "Finally Predicate" RRS feed

  • Question

  • A general principle for exception handling, is to catch only the specific exceptions that can be appropriately handled.  A corollary is "do not catch the 'System.Exception' base (unless in a static main of an exe)."

     

    The problem is that many developers don't have the discipline to enumerate dozens of catch blocks for specific exceptions...only for the purpose of *conditionally* freeing resources before bailing out.  Furthermore, the IDisposable / "using" idiom does not address the problem, because the implicit "finally" clause of a "using" statement does not employ *conditional* cleanup.

     

    I've come up with a solution to this problem, and I want to know what others think about it.  The specific scenario is a try block that needs "cleanup" **only if** any one of dozens of exceptions are thrown.  My solution is to skip using catch blocks altogether, in favor of what I will call a "finally predicate idiom," like this:

     

    public class myClass

    {

    bool MyMethodSuccess;

    public void MyMethod(){

    MyMethodSuccess = false;

    try {

    //begin section of potentially dozens of different discreet thrown exceptions.

    //makecall();

    //doSomething();

    //makecall();

    //doSomething();

    //makecall();

    //doSomething();

    //makecall();

    //doSomething();

    MyMethodSuccess = true;

    }

    finally{

    if (!MyMethodSuccess){

    //do cleanup;

    }

    }

    }

    }

     

    In the above code, the principle of "don't catch 'System.Exception' base" is upheld...but likewise the developer did not have to write dozens of catch blocks that each point to a cleanup routine.  What says the community?

     

    My own feeling is that the above approach might only be viable in a garbage collected languages (the above is C#), because the "finally predicate" might belong to an object instance that is itself on the program stack.  During unwinding, that reference will be freed - but the GC should still have a reference to the instance because it knows it must return to the finally clause after a suitable "catch" block is found upward on the stack.

    Tuesday, May 6, 2008 9:53 PM

Answers

All replies

  • > A corollary is "do not catch the 'System.Exception' base (unless in a static main of an exe)."

     

    Many people more loosely say that you should not catch System.Exception unless you rethrow it (e.g., after you perform your cleanup processing).

     

    This is explained here:

     

    http://msdn.microsoft.com/en-us/library/ms229007(VS.80).aspx

     

     

     

    Tuesday, May 6, 2008 11:09 PM
  • Can't say I ever had to use this pattern.  Every "makecall" method has to be responsible for restoring state if there's a chance that the exception might be caught.  They all need their own finally block.  Dozens of catch statements never happens, I'm lucky if I can recover from one.  If there are many state changes in a single function, possibly requiring the boolean flag, I refactor the code so there's only a few per method.  YMMV.
    Wednesday, May 7, 2008 12:32 AM
    Moderator