Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception thrown in catch and finally. CLR behavior vs. try-catch block [duplicate]

Tags:

I wrote simple C# console app:

class Mystery
{
    static void Main(string[] args)
    {
        MakeMess();
    }

    private static void MakeMess()
    {
        try
        {
            System.Console.WriteLine("try");
            throw new Exception(); // let's invoke catch
        }
        catch(Exception)
        {
            System.Console.WriteLine("catch");
            throw new Exception("A");
        }
        finally
        {
            System.Console.WriteLine("finally");
            throw new Exception("B");
        }
    }
}

The output given in console is:

try

catch

Unhandled Exception: System.Exception: A at Mystery.Program.MakeMess() in ...

It seems that CLR caught A and the finally block was not invoked at all.

But when I surround call to MakeMess() with try-catch block:

static void Main(string[] args)
{
    try
    {
        MakeMess();
    }
    catch(Exception ex)
    {
        System.Console.WriteLine("Main caught " + ex.Message);
    }
}

The output looks totally different:

try

catch

finally

Main caught B

It seems that Exception that propagates from MakeMess() is different when Exception is strictly handled outside of method.

What's the explanation of this behavior?

like image 898
elklepo Avatar asked May 05 '17 10:05

elklepo


People also ask

What happens if exception thrown in catch block finally?

Q #3) What happens when a catch block throws an exception? Answer: When an exception is thrown in the catch block, then the program will stop the execution. In case the program has to continue, then there has to be a separate try-catch block to handle the exception raised in the catch block.

Can you throw an exception from a catch or a finally block?

Some resource cleanup, such as closing a file, needs to be done even if an exception is thrown. To do this, you can use a finally block. A finally block always executes, regardless of whether an exception is thrown. The following code example uses a try / catch block to catch an ArgumentOutOfRangeException.

What is the difference between try catch finally statement and a throw statement?

The try statement defines the code block to run (to try). The catch statement defines a code block to handle any error. The finally statement defines a code block to run regardless of the result. The throw statement defines a custom error.

Does finally run even if I throw in catch?

The finally block executes regardless of whether an exception is thrown or caught.


1 Answers

The behavior you are seeing has nothing to do with a finally block throwing or not. You simply have an unhandled exception in your application, when that happens, all bets are off, including if finally blocks run or not:

From MSDN documentation:

Within a handled exception, the associated finally block is guaranteed to be run. However, if the exception is unhandled, execution of the finally block is dependent on how the exception unwind operation is triggered. That, in turn, is dependent on how your computer is set up. For more information, see Unhandled Exception Processing in the CLR.

Usually, when an unhandled exception ends an application, whether or not the finally block is run is not important. However, if you have statements in a finally block that must be run even in that situation, one solution is to add a catch block to the try-finally statement. Alternatively, you can catch the exception that might be thrown in the try block of a try-finally statement higher up the call stack. That is, you can catch the exception in the method that calls the method that contains the try-finally statement, or in the method that calls that method, or in any method in the call stack. If the exception is not caught, execution of the finally block depends on whether the operating system chooses to trigger an exception unwind operation.

If the finally block must run, then the solution is to do precisely what you've done in the second snippet: handle the unhandled exception.

like image 183
InBetween Avatar answered Sep 22 '22 11:09

InBetween