Why Catch and Rethrow an Exception in C#

Why catch and rethrow an exception in C#?

First; the way that the code in the article does it is evil. throw ex will reset the call stack in the exception to the point where this throw statement is; losing the information about where the exception actually was created.

Second, if you just catch and re-throw like that, I see no added value, the code example above would be just as good (or, given the throw ex bit, even better) without the try-catch.

However, there are cases where you might want to catch and rethrow an exception. Logging could be one of them:

try 
{
// code that may throw exceptions
}
catch(Exception ex)
{
// add error logging here
throw;
}

What is the proper way to rethrow an exception in C#?

You should always use the following syntax to rethrow an exception. Else you'll stomp the stack trace:

throw;

If you print the trace resulting from throw ex, you'll see that it ends on that statement and not at the real source of the exception.

Basically, it should be deemed a criminal offense to use throw ex.


If there is a need to rethrow an exception that comes from somewhere else (AggregateException, TargetInvocationException) or perhaps another thread, you also shouldn't rethrow it directly. Rather there is the ExceptionDispatchInfo that preserves all the necessary information.

try
{
methodInfo.Invoke(...);
}
catch (System.Reflection.TargetInvocationException e)
{
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(e.InnerException).Throw();
throw; // just to inform the compiler that the flow never leaves the block
}

Rethrowing an exception in C#

You do not have to bind a variable to the exception:

try
{
...
}
catch (Exception)
{
bqBusinessQuery.RollBackTransaction();
throw;
}

Actually, in your case, as you catch any exception, you do not have to even name the exception type:

try
{
...
}
catch
{
bqBusinessQuery.RollBackTransaction();
throw;
}

Or (as suggested @Zohar Peled) throw a new exception, using the caught exception as an inner exception. This way you both preserve the stack and give the exception more context.

try
{
...
}
catch (Exception e)
{
throw new Exception("Transaction failed", e);
}

If you actually want to use the exception for some processing (e.g. log it), but want to rethrow it intact, declare the variable, but use a plain throw:

try
{
...
}
catch (Exception e)
{
Console.WriteLine(e.Message);
throw;
}

Why exception filters are preferable to catching and rethrowing?

The advantages of exception filtering are more to do with when the filter doesn't match, not when it does match. If you remove all of the catch blocks except for the first one, and change the filter on the first catch block to when(e.code != 0), then the callstack of the exception would indicate it was thrown on line 16.

The old way of implementing this would be as follows:

    try
{
throw new specialException(); //line 16
throw new Exception("Weird exception");
//int a = Int32.Parse("fail");
}
catch (specialException e)
{
if(e.code != 0)
{
WriteLine("E.code isn't 0");
return;
}

throw;
}

In this case, the call stack will indicate that the exception was thrown at the throw statement, rather than on line 16.

C# - Rethrow exception in catch block, after return

The throw after return is never executed. The exception is not thrown to the caller. It is an unreachable code.

It doesn't make any sense, a method that throws an exception doesn't return anything to the caller (except the exception itself) . So just throw.

try
{
// return something valid
}
catch(Exception)
{
throw;
}

As for why it is not marked by Visual Studio as unreachable, I think it is a bug.

Edit:

If you throw an exception in the finally block, the exception bubbles up the stack to find a catch and the value is not returned.

Proper way to rethrow an exception

Alternative way to re-throwing the exception (using throw; as described in other answers) is to wrap the exception in inner exception. As described in MSDN, all custom exceptions should have at least four constructors, and one of them is

public InvalidDepartmentException(string message, System.Exception inner) : base(message, inner) { }

So if all your custom exceptions are like this, you could wrap the exception from Method3 as inner exception:

void Method2()
{
if(error)
{
throw(new Method2Exception("error"));
}

//Do something and call method3
try
{
Method3();
}
catch(Method3Exception exc)
{
throw new Method2Exception("error", exc); // exc is passed as inner exception
}
}

Then if you want to inspect the inner exception in Method1, you can use property InnerException:

void Method1()
{
try
{
Method2();
}
catch(Method2Exception ex)
{
if(ex.InnerException != null)
{
var message = ex.InnerException.Message;
// Do what you need with the message
}
}
}

C# How to rethrow an exception from an outer catch

There is no way to rethrow an exception from an outer catch block inside an inner catch block. The best way to achieve this pattern is to note whether or not the inner operation succeeded :

try {
something();
} catch (MyException e1) {
bool recovered=false;
try {
somethingElse();
recovered=true;
} catch {

}
if (!recovered) {
throw;
}
}

Catching an Exception and rethrowing in C# - can it keep its type?

Yes you can do that. Inside your first catch, the exception is simply treaded as the base Exception but when you rethrow it the next catch will catch it as it's real type.

When you rethrow the exception please use throw; not thrown ex; see here why

C# rethrow exception without try-catch block

Yes, just don't do anything at all. If there's no try-catch block, your exception will bubble up the call stack until it finds one.

Note that there are no checked exceptions in C#, so it's the default implicit behavior.



Related Topics



Leave a reply



Submit