Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# - Rethrow an exception without setting it to an variable

As all of you probably know, catching and re-throwing a exception in c# this way is evil, because it destroys the stack trace:

try
{
    if(dummy)
        throw new DummyException();
}
catch (DummyException ex)
{
    throw ex;
}

The right way to re-throw an exception without loosing the stack trace is this:

try
{
    if(dummy)
        throw new DummyException();
}
catch (DummyException ex)
{
    throw;
}

The only problem with this is that I get a lot of compilation warnings: "The variable 'ex' is declared but never used". If you have a lot of these, a useful warning may be hidden in the garbage. So, that's what I did:

try
{
    if(dummy)
        throw new DummyException();
}
catch (DummyException)
{
    throw;
}
catch(AnotherException ex)
{
    //handle it
}

This seems to work, but I'd like to know if there is any downside of re-throwing an exception that is not set to an variable. How does .net threats this?

Thanks in advance

Edit: I've changed my code a little bit to make clearer what I wanted to do, as some had misunderstood

like image 981
Ortiga Avatar asked May 02 '11 15:05

Ortiga


2 Answers

I'd like to know if there is any downside of re-throwing an exception that is not set to an variable.

No, there's no downside at all. A variable is only needed if you want to reference the exception in your code, but since you don't need to do that with a throw statement, you don't need a variable at all.

And you have exactly the right idea in attempting to eliminate "noisy" compiler warnings. They have a tendency to bury important errors that you do want to fix, and getting a clean build is always important. The best solution is simply to rewrite the code to use a parameterless catch clause.

However, be aware that in 82% of cases that I see*, it's a mistake to write code that uses throw at all. You generally shouldn't catch exceptions that you don't know how to handle and your only intended "handling" strategy is to rethrow them. There are cases where even using throw can reset the call stack, causing you to lose important debugging information. There are also better alternatives for logging exceptions to catching/rethrowing. You can find more information in the answers to these questions:

  • Main method code entirely inside try/catch: Is it bad practice?
  • what can lead throw to reset a callstack (I'm using "throw", not "throw ex")

There's absolutely nothing wrong with letting exceptions bubble up and handling them all in a central place. The rule to keep in mind is that you shouldn't use exceptions for flow control. But there's nothing wrong with throwing an exception in low level code, and showing the user an error message higher up the stack in UI code. Read Microsoft's Best Practices for Handling Exceptions for some general tips.


* Slightly more than the percent of statistics that are made up on the spot.

like image 89
Cody Gray Avatar answered Nov 02 '22 16:11

Cody Gray


There is no downside to that. You are simply telling the compiler "I plan to catch this exception but I have no need for a reference to the actual exception", it doesn't affect how things are thrown or how exceptions work. Your latter example is the ideal way to do what you want, however if you are merely going to immediately throw; with nothing else whatsoever in the block, then why catch at all?

like image 23
Matt Greer Avatar answered Nov 02 '22 16:11

Matt Greer