Luke Wyatt
Luke Wyatt

Reputation: 1136

C# Scope of exception handling

What is the scope of exception handling in C#. I am currently reviewing some code from another programmer on my team and he has a function laid out somewhat like this:

private void function1() {
try {
function2();
}
catch (Exception ex) {
EmailException(ex.message());
}}

private void function2() {
try {
// Do stuff
}
catch (Exception ex) {
// Handle it here
}}

The bulk of the processing code is in function2. However his reporting handling is in function1. Will an exception in function2 kick back to the function1 handler that sends the report?

Edit: Thanks for your responses, they all were very helpful!

Upvotes: 3

Views: 1945

Answers (5)

supercat
supercat

Reputation: 81159

In .net, when an exception occurs, the system will search through the nested try blocks on the stack to determine if there is a catch block that can catch the exception. This occurs before any finally blocks run. If there isn't any block that can catch the exception, the system will invoke an "unhandled exception" handler without running any finally blocks.

If the system that does determine that there is a block that can catch the exception, it will start unwinding the stack and run finally blocks associated with inner try blocks until either it has unwound the stack all the way to the catch block it found, or an exception gets thrown in the execution of a finally block. In the latter situation, the previous exception will be abandoned and not processed further; exception handling will start afresh with the newly-thrown exception.

Although there is a semantic difference between wanting to catch an exception, versus merely wanting to act upon it (but let it be regarded as uncaught), there is no clean way to express that distinction in C#; code which catches an exception is expected to resolve it. The best one can do in C# is use a catch (indicating to the system's exception-processing logic to think one is going to catch the exception) and then use a throw, to indicate one doesn't want to resolve it after all (this will occur after inner "finally" blocks have run). In some other languages such as vb.net, it is possible to act upon exceptions, without catching them, before finally blocks run. While there aren't a huge number of cases where a catch and throw is different from capturing an exception without catching it, there are few cases where the distinction matters. If one is using C# and one wishes to avoid being hostile to surrounding code which might want to capture exceptions from inner code before finalizer blocks run, the best approach is probably to write an exception-handling wrapper method written in vb (or have someone else do it), compile it to a DLL, and then use lambdas to feed such a function methods for it to invoke within a suitable try/filter/catch/finally block.

Upvotes: 1

Conrad Frix
Conrad Frix

Reputation: 52645

Will an exception in function2 kick back to the function1 handler that sends the report?

No unless

  • An exception occurs outside of function2's try block
  • An exception occurs inside the function2 exception block
  • An exception is thrown e.g. trow or trow ex from function2's exception block
  • An exception is raised in function2's try block that is automatically retrown like ThreadAbortException

Upvotes: 2

Andras Zoltan
Andras Zoltan

Reputation: 42343

Only if

a) function2 re-throws the original exception with throw or a new exception with throw new ...

b) an unexpected exception occurs inside function2's catch block or after it (which actually in this case is impossible since the catch block is the last thing that happens in function2).

Upvotes: 4

Austin Salonen
Austin Salonen

Reputation: 50225

Assuming // Handle it here does not rethrow the exception, function1 will never see the original exception.

It is possible function2 will raise a new issue in its catch though, much like it's possible EmailException could err in function1.

Upvotes: 4

Cameron
Cameron

Reputation: 98746

No, an exception propagates only until it is caught.

However, you can re-throw the exception at the end of the catch in function2, leading to the desired behaviour:

private void function2() {
    try {
        // Do stuff
    }
    catch (Exception ex) {
        // Handle it here
        throw;    // <- Re-throw the exception.
                  // Note this is different from `throw ex;`
    }
}

Upvotes: 2

Related Questions