How to 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
}

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
}
}
}

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;
}

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;
}
}

How to log an exception and rethrow as the actual type

You can just use throw; instead of throw new... or instead of throw ex;

Once an exception is thrown, part of the information it carries is the
stack trace. The stack trace is a list of the method call hierarchy
that starts with the method that throws the exception and ends with
the method that catches the exception. If an exception is re-thrown by
specifying the exception in the throw statement, the stack trace is
restarted at the current method and the list of method calls between
the original method that threw the exception and the current method is
lost. To keep the original stack trace information with the exception,
use the throw statement without specifying the exception.

More here : MSDN

Can I rethrow an existing exception in an expression switch case?

Just catch the specific Exception type:

try
{
// Some code...
}
catch (ExceptionA exA)
{
// maybe log this
return "something";
}
catch (ExceptionB exB)
{
// maybe log this
return "something else";
}
catch (Exception ex)
{
// log this
throw; // throw keeps the original stacktrace as opposed to throw ex
}

As you have asked how to do this with the switch, this should work as well:

try
{
// Some code...
}
catch (Exception ex)
{
switch(ex)
{
case ExceptionA exA:
return "something";
case ExceptionA exA:
return "something else";
default:
throw;
}
}

C#: Rethrow an exception from a variable while preserving stack trace

That's where ExceptionDispatchInfo comes into play.

It resides inside the System.Runtime.ExceptionServices namespace.

class Program
{
static void Main(string[] args)
{
ExceptionDispatchInfo edi = null;

try
{
// stuff
throw new Exception("A");
}
catch (Exception ex)
{
edi = ExceptionDispatchInfo.Capture(ex);
}

edi?.Throw();
}
}

The output:

Unhandled exception. System.Exception: A
at EDI_Demo.Program.Main(String[] args) in C:\Users\...\Program.cs:line 16
--- End of stack trace from previous location where exception was thrown ---
at EDI_Demo.Program.Main(String[] args) in C:\Users\...\Program.cs:line 24
  • Line 16 is where throw new Exception("A"); is called
  • Line 24 is where edi?.Throw(); is called

Best practices for catching and re-throwing .NET exceptions

The way to preserve the stack trace is through the use of the throw; This is valid as well

try {
// something that bombs here
} catch (Exception ex)
{
throw;
}

throw ex; is basically like throwing an exception from that point, so the stack trace would only go to where you are issuing the throw ex; statement.

Mike is also correct, assuming the exception allows you to pass an exception (which is recommended).

Karl Seguin has a great write up on exception handling in his foundations of programming e-book as well, which is a great read.

Edit: Working link to Foundations of Programming pdf. Just search the text for "exception".



Related Topics



Leave a reply



Submit