Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 896
Michael Stum Avatar asked Dec 29 '10 08:12

Michael Stum


People also ask

Which is better throw or throw ex?

Unlike throw ex, throw provides all stack information. The main difference between throw and throw ex in C# is that throw provides information about from where the exception was thrown and also about the actual exception while throw ex provides information only about from where the exception was thrown.

Why should we throw exception?

It is good programming practice to avoid this usage where possible. If null is a reasonable value for the stated purpose of a method, or if a method is expected to fail often in the normal course of operation, then it is reasonable to return null to indicate failure; otherwise it is better to throw an exception.

Should you use exceptions?

Exceptions should only be used in exceptional circumstances and therefore should be used sparingly. For example, it is correct to use an exception when you are attempting to access the Twitter API and do some processing because if this fails it is an exceptional circumstance.


4 Answers

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.
like image 60
Henk Holterman Avatar answered Oct 02 '22 23:10

Henk Holterman


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.

like image 44
Damien_The_Unbeliever Avatar answered Oct 02 '22 22:10

Damien_The_Unbeliever


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.

like image 42
Tim Lloyd Avatar answered Oct 02 '22 22:10

Tim Lloyd


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;
}
like image 30
Arseni Mourzenko Avatar answered Oct 02 '22 22:10

Arseni Mourzenko