Is there any real world reason to use throw ex?

In C#, throw ex is almost always wrong, as it resets the stack trace.

I just wonder, is there any real world use for this? The only reason I can think of is to hide internals of your closed library, but that's a really weak reason. Apart from that, I've never encountered in the real world.

Edit: I do mean throw ex, as in throwing the exact same exception that was caught but with an empty stacktrace, as in doing it exactly wrong. I know that throw ex has to exist as a language construct to allow throwing a different exception (throw new DifferentException("ex as innerException", ex)) and was just wondering if there is ever a situration where a throw ex is not wrong.

Answers


There is no valid reason to re-throw exception objects i.e. 'throw ex'.

It's a language\compiler feature that's possible although doesn't add any value in practice over the negative effect it has. This is a similar situation to being able to write code to access members on null references - it's of course possible but has no value, e.g.:

    //Possible but not useful.
    object ref1 = null;

    ref1.ToString();

Being able to re-throw exception objects is unfortunate and very often misunderstood by rookies and experienced coders alike, that is until you get an unhandled exception in production with a truncated stack trace logged.

There is the tenuous feeling that it could be used to intentionally hide stack trace information, but throwing a new exception would be the correct way to do this.

I would go as far as to say that being able to re-throw exception objects (i.e. 'throw ex') is a design flaw - it's just too easy to do the wrong thing. However, I suspect that this is a design trade-off in the compiler for performance reasons as it would incur an overhead to validate that 'throw ex' was not a 're-throw'. I'm sure there are many such trade-offs.


I have never seen it used on purpose, but that of course doesn't mean anything.

Let's look at the alternatives:

catch(Exception ex)
{
    // do stuff (logging)
    throw;                                // a) continue ex
    throw new SomeException("blah", ex);  // b) wrap
    throw new SomeException("blah");      // c) replace
    throw ex;                             // d) reset stack-trace
}

Both c) and d) are dropping the stack-trace, the only 'advantage' of d) that I can see is that throw ex; preserves the exact type and possible extra properties (SQL error) of ex.

So is there ever a case where you want to keep all information of an exception except the stack-trace? Not normally, but some speculation:

  • at the boundary of an obfuscated library. But c) would look like a better option here.
  • at the call site to some generated code, like in the RegEx class.

If you stop to think about it, throw ex is actually used pretty frequently - except with an unnamed local variable. It would be pretty difficult to (re-)design the language so that:

throw new ArgumentException();

was valid, but

var ex = new ArgumentException();
throw ex;

was invalid (and then extend this for tracing more complex variable assignments). I.e. throw ex is the "normal" form of the throw statement, but it is usually wrong when re-throwing an already caught exception.


throw ex is just an error or a typo made by people who don't know or forget about throw;.

It can be intended probably in one case only, pointed by other people in their answers: the situation where you don't want the proper stack trace to be sent to the caller, but you still want to keep the type of the exception previously thrown. In practice, I can hardly imagine the case when somebody will need it, and will not use throw new SomeCustomException(...) instead.

FxCop rule CA2200 RethrowToPreserveStackDetails goes in the same way, inviting you to rethrow an exception correctly by using throw;:

try
{
    // ...
}
catch (SomeException ex)
{
    Logger.AddException(ex);
    throw;
}

Here are two real-world applications of rethrowing existing exception objects:

Reflection

When calling code through reflection, any exceptions thrown will be wrapped in TargetInvocationException. But you may want/need to handle exceptions past the reflection "barrier". In this case, the wrapping will complicate exception handling code. Instead you can unwrap the original exception and rethrow.

If you are on .NET 4.5+, you can use ExceptionDispatchInfo to preserve the original stack trace:

MethodInfo someMethod = ...
try
{
    someMethod.Invoke();
}
catch (TargetInvocationException e)
{
    ExceptionDispatchInfo.Capture(e.InnerException).Throw();
}
Task API

In the .NET Task API, exceptions thrown during execution of tasks are wrapped in AggregateException. When using async/await, the framework will perform unwrapping under the covers in order to throw the original exception instead of the wrapper AggregateException.

Apart from BCL code needing to rethrow existing exceptions when auto-unwrapping, there are cases where you cannot use async/await and therefore need to manually unwrap and rethrow. For a practical example of this, check out the internal uses of TaskExtensions.WaitAndUnwrapException in the AsyncContext implementation in Stephen Clearys excellent AsyncEx project.


You may want to log the exception, log it and then throw it as 'throw ex' to the upper layer. You may also want to do logging in this layer too but this may have nothing to to with the layer that you got the exception or you may not need the details of the exception since you already logged it.

Lets say you have:

Public int GetAllCustomers()
{
     try
     {
          return data.GetAllCustomers()
     }
     catch()
     {
         Logger.log("Error calling GetAllCustomers");
     }
}
     //data
Public static int GetAllCustomers()
{
     try
     {
          //db operations...
     }
     catch(Exception ex)
     {
          Logger.log(ex.Stacktrace);
          throw ex;
     }
}

Need Your Help

pointer to a structure within a structure in C

c pointers struct

I have a structure (let's call it structure1) which holds a pointer to another structure (structure2), this way.

how to replace all the occurrence in a string with a different number

python

I have never used python in my life. I need to make a little fix to a given code.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.