Something you probably didn’t know about Try, Catch & Finally block

July 29, 2019


We all must have used the try, catch & finally block. While using these blocks, we simply used it the way like:
try
{
    //do something
}catch (Exception ex)
{
    //ex exception occurred
}finally
{
    //do some final executions
}
This is just the basic & the proper usage of try, catch & finally blocks. But still, there are some scenarios that may become difficult when used with the try-catch block.

Use Case

Consider a function returning an integer value. The code snippet inside the function should use be written inside a try-catch block along with a corresponding finally block.
public static void Main(string[] args)
{
    Console.WriteLine(GetSomeValue());
}private static int GetSomeValue()
{
    try
    {
        //do something
    }
    catch
    {
        //exception occurred
    }
    finally
    {
        //finally block execution
    }
}

Scenario 1 — Returning value from the try, catch & finally blocks

What if each of the try, catch & finally block returns a value?
What will be the returned value?
Will this be a valid code?
Let’s answer all these questions.
Consider the following method:
public static void Main(string[] args)
{    Console.WriteLine(GetSomeValue());
}private static int GetSomeValue()
{
    try
    {
        return 1;
    }
    catch
    {
        return 2;
    }
    finally
    {
        return 3;
    }
}
Visual studio has shown an error that “Control cannot leave the body of a finally clause”.

The above code is invalid code.
Finally block cannot return values. They are meant for only some code execution like logging, some garbage collection stuff, etc. Thus removing the integer return value from the finally block worked & visual studio was able to run the code.
Correct Code:
private static int GetSomeValue()
{
    try
    {
        return 1;
    }
    catch
    {
        return 2;
    }
    finally
    {
        //do some other stuff rather than returning value
        Console.WriteLine("Finally block called");
    }
}
Also, now if we try to call the method & print the returned value in the console with the command:
Console.WriteLine(GetSomeValue());
We get the output:
> Finally block called
> 1
So what actually happened here is the method GetSomeValue() was called & its try block was executed as there was no error. The try block returned the value to the caller but before actually returning the value, the finally block was executed which printed the output to the console & we get the above output.

SCENARIO 2 — Exception in the try, catch & finally blocks

We all know we use catch blocks to catch the exceptions that originate from the try block but what if an exception occurs in the other two blocks. Let’s see what happens in such cases.

Exception in the try block

private static void GetSomeValue()
{
    try
    {
        Console.WriteLine("Try executing with some exception");
        throw new Exception("DummyException");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message + " exception occurred");
    }
    finally
    {
        Console.WriteLine("Finally block called");
    }
}
The above program is expected to run the usual way & produces the following output when executed.
Console Output
> Try executing with some exception
> DummyException exception occurred
> Finally block called

Exception in the catch block

private static void GetSomeValue()
{
    try
    {
        try
        {
            Console.WriteLine("Try executing inner block");
            throw new Exception();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message + " exception occurred");
            throw new Exception("DummyException");
        }
        finally
        {
            Console.WriteLine("Inner Finally block called");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message + " exception catched outside");
    }
    finally
    {
        Console.WriteLine("Outer Finally block called");
    }
}
If an exception occurs inside the catch block, the exception is propagated to the above level. In the example above, we threw an exception from the inner catch block. The exception is propagated to the catch of the above level & exception is caught in the outer catch block.
The method when executed yields the following result:
Console Output (comments are for referential prupose only):
> Try executing inner block //from inner try block
> Exception of type 'System.Exception' was thrown. exception occurred //from inner catch block
> Inner Finally block called //from inner finally block
> DummyException exception catched outside //from outer catch block
> Outer Finally block called //from outer finally block

Exception in finally block

private static void GetSomeValue()
{
    try
    {
        try
        {
            Console.WriteLine("Try executing inner block");
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message + " exception occurred");
        }
        finally
        {
            Console.WriteLine("Inner Finally block called");
            throw new Exception("DummyException");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message + " exception catched outside");
    }
    finally
    {
        Console.WriteLine("Outer Finally block called");
    }
}
The case when an exception occurs in the finally block is same as the case when an exception occurs in the catch block.
The code above when executed yields the following result:
Console Output:
> Try executing inner block
> Inner Finally block called
> DummyException exception catched outside
> Outer Finally block called
Notice here also, the exception propagates from lower level to upper level.

You Might Also Like

0 comments

Follow by Email