tags:

views:

134

answers:

8

Hi,

try  
{  
    throw new Exception("test");  
}  
finally  
{  
    //Inspect the exception ????  
    //Log(Exception);  
}

Is there a way to get the exception from the run-time in the finally?
I cannot use a catch :-)

Thanks for your answers.
I cannot use a catch because its not actually my code(to refactor).
We want to wrap a piece of code like that:

using(CriticalFlow(policy))  
{  
   //Not my code.  
   flow.Succeeded();  
}

In CriticalFlow finally block we need to inspect the exception, if succeeded was not called, and alert whoever by whichever means.
I hope it throws some light to the original question.

Thanks again.

+4  A: 

When you reach the finally block the exception instance is already out of scope. The whole idea with try blocks is to have a place to inspect the exceptions. What you can do if you do not want to catch it is to simply rethrow it:

try
{
    // some exception is thrown
}
catch (Exception ex)
{
    // do some logging or so
    throw;
}
Fredrik Mörk
As far as i know the finally is called before a proper exception handler is executed, and therefore the exception is still alive.
eyan
@eyan: that is is alive does not mean that it is in scope ;o) If you want the exception to be in scope in the finally block, you will need to use dneomatrix' approach (but don't forget to rethrow in that case).
Fredrik Mörk
As i wrote i cannot use a catch, since i need to handle the exception in CriticalFlow, i was thinking of something like Diagnostic.GetException() sort of solution.Thanks.
eyan
A: 

No, the exception is thrown up in the stack until it gets caught in a catch block.

Why are you not able to use catch ? :? You can catch the exception do wat you want to do with it, and re-throw it if you want.

Frederik Gheysels
As i tryed to explain i need to handle the error in one place the CriticalFlow class, and i dont want to depand on the "controled" flow the forward the exception to me.
eyan
A: 

I'm sorry but that is impossible...

Ronald Wildenberg
+2  A: 

No, you can't. If you can modify the rest of the code you could write:

Exception e = null;
try
{
    e = new Exception("test");
    throw e;
}
finally
{
    // Examine e
}

but you can't do anything "normally".

Could you wrap the whole thing in a logging method? Delegates could be helpful here, e.g.

LogExceptions(delegate
    {
        try
        {
            throw new Exception("test"0;
        }
        finally
        {
            // Not logged yet
        }
    }
);

Where LogExceptions would just try the specified action, catch any exceptions, log them and rethrow.

Jon Skeet
+7  A: 
Exception helper;

try
{

}
catch (Exception ex)
{
    helper = ex;
}
finally
{
   if (helper != null)
   {
      process helper
   }
}
DNeoMatrix
Do not forget to rethrow the exception at the end of the catch bloc in order to maintain original behaviour. Btw, managing exception should be done in a catch bloc. It is the reason they are. I don't understand why you cannot use it.
Tyalis
A: 

No, you cannot directly access exception object in finally block. What you can do, however, is to catch an exception in a catch block, store it in a local variable and then rethrow it using throw; statement.

Anton Gogolev
A: 

why in finally ? finally will run whether an exception happaned or not, log exception in catch

Adinochestva
A: 

This code can clarify our intention:

using (CriticalFlow cf = new CriticalFlow())
            {
                // code which can throws
                cf.Completed();
            }

public class CriticalFlow : IDisposable
    {
        private bool _completed = false;

        public void Completed()
        {
            this._completed = true;
        }

        #region IDisposable Members

        public void Dispose()
        {
            if (this._completed == false)
            {
               // can i peek the exception at this point?
            }
        }

        #endregion
    }