Order of Operations in nested try..catch..finally

Let’s dive in and take a look at some common and not-so-common exception handling arrangements.

Everyone should be familiar with the standard try..catch..finally construct:

try {
    //this code will run only until an exception is thrown
}
catch {
    //this code will run only IF and exception is thrown
}
finally {
    //this code will run always AFTER the try and/or catch blocks have been executed
}

Here is a less common arrangement. When might this be appropriate to use?

try {
    try {
    }
    catch {
    }
}
finally {
}

Now let’s look at some concrete examples. Consider this code snippet:

string output = "";
try {
    output += "A";
    try {
        throw new InvalidOperationException("1");
        output += "B";
    }
    finally {
        output += "C";
    }
    output += "D";
}
catch (Exception e) {
    output += e.Message;
}
finally {
    output += "E";
}
Console.WriteLine("Output: " + output);
Output: AC1E

There are two interesting points to note here: 1) the exception is raised to the outer try..catch. It is not suppressed by the nested try..finally, and 2) the nested finally block executes before the outer catch!

Now consider this code snippet:

string output = "";
try {
    output += "A";
    try {
        throw new InvalidOperationException("1");
        output += "B";
    }
    finally {
        throw new InvalidOperationException("2");
        output += "C";
    }
    output += "D";
}
catch (Exception e) {
    output += e.Message;
}
finally {
    output += "E";
}
Console.WriteLine("Output: " + output);
Output: A2E

Like the first example, the exception is raised to the outer try..catch, but the difference here is that the first exception is suppressed! Only exception “2” is captured! The short answer is do not throw exceptions from a catch or finally.

Leave a Reply