In some instances, an exception might be thrown that causes another exception to be thrown further up the call stack.
We saw this when looking at How to re-throw an exception.
When this happens, the original exception that was thrown is referred to as the inner exception.
Being able to see the inner exception from inside another exception gives us more context into where an error occurred.
Catching an inner exception
Let's take a look at the following example:
using System;
using System.IO;
class HandleInnerExceptions
{
static void Main()
{
try
{
ParseNumber("notANumber");
}
catch (Exception e)
{
Console.WriteLine($"Inner Exception: {e.InnerException.Message}");
Console.WriteLine($"Outer Exception: {e.Message}");
}
}
static void ParseNumber(string number)
{
try
{
// This will fail, and throw a FormatException
var num = int.Parse(number);
}
catch (FormatException fe)
{
try
{
// This file doesn't exist, and will throw a FileNotFoundException
var log = File.Open("logs.txt", FileMode.Open);
}
catch
{
throw new FileNotFoundException("Could not open the log!", fe);
}
}
}
}
A number of things happen here:
- By passing a string into int.Parse, we should expect a FormatException to be thrown.
- This is then caught, and in the catch block we try to open a log file that doesn't exist, throwing a FileNotFoundException.
- We then re-throw the exception with our own message, and the inner exception, to be caught by Main.
- When Main catches the exception e, it will contain the inner exception e.innerException.
Executing this code will display the following:
Inner Exception: Input string was not in a correct format.
Outer Exception: Could not open the log!