What happens if a final block throws an exception?
OR
How to handle exceptions that occur in a final block?
Three things happen.
Let's understand with an example.
Step 1. First, we will create a console application named ExceptioninFinallyblock.
Step 2. Now here, we will create a method named FinallyBlock and include a try, catch, and finally block.
Now we write some code within the final block that would cause an exception to occur with the following code.
using System;
namespace ExceptioninFinallyblock
{
class Program
{
static void Main(string[] args)
{
FinallyBlock(); // Calling the method
}
public static void FinallyBlock()
{
try
{
}
catch
{
}
finally
{
int result = Convert.ToInt32("THREE"); // Convert to integer
}
}
}
}
Step 3. So notice that at the higher level, where we called the FinallyBlock(), the method doesn't have any exception handling mechanism there. When we run the program, the application will terminate with the exception that occurs in the final block.
Now we will provide an exception-handling mechanism at the higher level in the Main() method, where we are actually calling the FinallyBlock() method. So we are using the exception handling mechanism.
Here we have the opportunity to handle the exception that occurs in the final block of the FinallyBlock() method. Here we write an exception message to the console with the following code.
using System;
namespace ExceptioninFinallyblock
{
class Program
{
static void Main(string[] args)
{
try
{
FinallyBlock(); // Calling the method
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public static void FinallyBlock()
{
try
{
}
catch
{
}
finally
{
try
{
int result = Convert.ToInt32("THREE"); // Convert to integer
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
}
Now run the program. We will see that the application does not crash since we have an exception-handling mechanism at a higher level. We have the opportunity to handle the exception.
Step 4. So what is the second point?
So at the final block where the exception is thrown, let's include a Console.WriteLine() statement. That line is present before the exception occurs, so this piece of code will execute.
using System;
namespace ExceptioninFinallyblock
{
class Program
{
static void Main(string[] args)
{
try
{
FinallyBlock(); // Calling the method
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public static void FinallyBlock()
{
try
{
}
catch
{
}
finally
{
Console.WriteLine("This line will be executed"); // Statement before exception occurs
try
{
int result = Convert.ToInt32("THREE"); // Here an exception will occur
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
}
Now we will include one Console.WriteLine() statement after the line where the exception occurs so the execution will stop at this line and the Console.WriteLine() statement will not be executed.
using System;
namespace ExceptioninFinallyblock
{
class Program
{
static void Main(string[] args)
{
try
{
FinallyBlock(); // Calling the method
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public static void FinallyBlock()
{
try
{
}
catch
{
}
finally
{
Console.WriteLine("This line will be executed"); // Statement before exception occurs
try
{
int result = Convert.ToInt32("THREE"); // Convert to integer
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine("This line will Not be executed"); // Statement after exception occurs
}
}
}
}
Now let's run and see the output. The first line is printed that is written before the exception occurs.
And the second line that is written after the exception occurs is not printed because at the point where the Exception occurs, the execution will stop, and the statements after the exception will not be executed.
So the "finally" block execution stops at the point where the exception is thrown.
Step 5. Now the third point.
Let's understand with an example.
Now we throw an exception in the try block and in the final block by the following code.
using System;
namespace ExceptioninFinallyblock
{
class Program
{
static void Main(string[] args)
{
try
{
FinallyBlock(); // Calling the method
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public static void FinallyBlock()
{
try
{
throw new Exception("Try Block Exception");
}
finally
{
throw new Exception("Finally Block Exception");
}
}
}
}
Now run the program so we are able to handle the exception that are occurs in the finally block. But what about the exception that occurs in the try block?
So we know that whether the exception occurs or not, the final will execute. It is guaranteed to execute.
Now, this exception will occur in the try block, and we are not handling the exception within this method.
And there is another exception occurring within the finally block, so as a result the original exception that occurred in the try block is lost. So the third point it is.