The mystery of double exclusions

Here's an interesting question. I have a system that is trying to run some initialization code. If that fails, we call the deinitializer to clear everything.

Since we are calling the deinitializer in exception handling, we run the risk that both initialization and deinitialization will fail, and presumably now it seems that we have to throw two exceptions.

It seems unlikely that we will. So what's going on and what should the code be doing here?

      try { /* init code here */ }        
      catch (Exception ex)
      {
         try
         {
            _DeinitializeEngine();
         }
         catch (Exception ex2)
         {
            throw new OCRException("Engine failed to initialize; ALSO failed to deinitialize engine!", ex2);
         }
         finally
         {
            throw new OCRException("Engine failed to initialize; failed to initialize license!", ex);
         }
      }

      

+1


source to share


4 answers


If your cleanup code doesn't work and you can't leave the application in a clean and known state, I would allow the exception unhandled (or catch it with an UnhandledException event to log it), then close the application.



Because if you can't handle the first exception, what's the point in catching the second exception?

+1


source


You shouldn't throw a finally block. Instead, use the InnerException value to add information to the cast.

Update

What you need to do is catch and rethink the "history" of the exception, this is done with an InnerException. You can edit it when creating a new exception. This is a piece of code I just wrote to illustrate the idea that I am explaining in all the comments below.



    static void Main(string[] args)
    {
        try
        {
            principalMethod();
        }
        catch (Exception e)
        {
            Console.WriteLine("Test : " + e.Message);
        }
        Console.Read();
    }

    public static void principalMethod()
    {
        try
        {
            throw new Exception("Primary");
        }
        catch (Exception ex1)
        {
            try
            {
                methodThatCanCrash();
            }
            catch
            {
                throw new Exception("Cannot deinitialize", ex1);
            }
        }
    }

    private static void methodThatCanCrash()
    {
        throw new NotImplementedException();
    }

      

You don't need to use a double throw with completion. If you put a breakpoint on the console Console.WriteLine (...). You will notice that you have all traces of exceptions.

+8


source


If I understand your problem correctly, here's what I would do:

try { /* init code here */ }            
catch (Exception ex)
{
    // Passing original exception as inner exception
    Exception ocrex = new OCRException("Engine failed to initialize", ex);

    try
    {
        _DeinitializeEngine();
    }
    catch (Exception ex2)
    {
        // Passing initialization failure as inner exception
        ocrex = new OCRException("Failed to deinitialize engine!", ocrex);            
    }
    throw ocrex;
}

      

+1


source


You have two possible exception conditions: one in which the first method failed, and one in which both methods failed.

You have already defined your own exception class. So create another (or continue with the first) with the RelatedException

or property PriorException

. When you have thrown the exception in the second case, keep a reference to the first exception in this property.

It is up to the exception handler to catch this exception to figure out what to do with the second exception.

0


source







All Articles