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
How to Delete an Element from an Array in C#
Calculate Date from Week Number
Mocking Extension Methods With Moq
Convert Ienumerable to Datatable
Assign Bitmapimage from Resources.Resx to Image.Source
How to Find the Number of Cpu Cores Via .Net/C#
.Net Httpclient. How to Post String Value
Calculate the Number of Business Days Between Two Dates
Asp.Net MVC: Custom Validation by Dataannotation
Reflection: How to Invoke Method With Parameters
Getting All Types in a Namespace Via Reflection
Sort a List from Another List Ids
Conditionally Change CSS Class in Razor View
My Algorithm to Calculate Position of Smartphone - Gps and Sensors
How to Run Servicestack on Linux/Mono
How to Tell Whether a Point Is to the Right or Left Side of a Line