3

I have some code which catches the exception, rolls back the transaction and then rethrow the exception.

catch ( Exception exSys )   {
    bqBusinessQuery.RollBackTransaction();
    throw exSys ;
}

If I use this code, VS Code analysis throws warning saying

Use 'throw' without an argument instead, in order to preserve the stack location where the exception was initially raised.

If I use the code

catch ( Exception exSys )   {
    bqBusinessQuery.RollBackTransaction();
    throw;
}

then I get a warning saying

The variable 'exSys' is declared but never used

How should I solve this problem?

Edit I tried this method, but it doesn't work. system.exception class requires an extra message, along with inner exception. If I do that, it will throw a new message overriding the message from the original exception. I don't want to get the new exception, I want to throw the same exception with same message.

    catch (System.Exception ex)
    {
        throw new System.Exception(ex);
    }

Edit

        catch (System.Exception ex)
        {
            throw new System.Exception("Test",ex);
        }

Tried this method. And then manually caused an exception using throw new Exception("From inside");. Now, ex.Message returns "Test" instead of "From inside". I want to keep that "From inside" message as is. This suggested change will cause problem with error display code everywhere. :/

jitendragarg
  • 945
  • 1
  • 14
  • 54

2 Answers2

9

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;
}
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
4
catch (Exception)   
{
    bqBusinessQuery.RollBackTransaction();
    throw;
}

If you don't plan on using the exception (e.g. passing the message somewhere) then you don't need to pull it out into a variable. You can simply catch, do custom thing and throw.

Kyle Muir
  • 3,875
  • 2
  • 22
  • 27
  • We do in some cases, pass the message. For example, when query validation fails, `throw new Exception("custom message");` is common in the application. Then the same is forwarded to the outermost calling function which updates the UI to display error. – jitendragarg May 11 '16 at 08:19
  • In that case you should `throw new exception("custom message", originalException)` so you don't lose the stack trace – Kyle Muir May 11 '16 at 08:21
  • 1
    for the splendid use of _pink_ you get a +1 –  May 11 '16 at 08:21
  • @KyleMuir Can I do `throw new exception(originalException)`. I am not trying to add any new message, just preserving the original message that was there when exception first occurred. E.g. `execute query` function throws exception saying `primary key already exists`, then i just want to rollback the transaction and let the same exception message pass through. – jitendragarg May 11 '16 at 08:25
  • @jitendragarg Yup, nothing wrong with doing that. We often catch generic exceptions and wrap them up with our own custom ones so we can catch them further up and deal with them. E.g. a custom DatabaseException or whatever. – Kyle Muir May 11 '16 at 08:27
  • Great. Thanks. That should work then. :) – jitendragarg May 11 '16 at 08:30
  • Wait, now I have new problem. ` catch (System.Exception ex) { throw new System.Exception(ex); }' does not work. It gives me an error saying best overloaded method has invalid argument. It does need an error message. – jitendragarg May 11 '16 at 08:35
  • @jitendragarg You're quite correct. Sorry, it's late and I'm tired. `catch (Exception ex) { throw new Exception("Database Exception", ex); }` or similar should work fine :) – Kyle Muir May 11 '16 at 08:38
  • That causes another problem. Check the question's edit. – jitendragarg May 11 '16 at 08:41
  • 1
    What about: `catch (Exception ex) { throw new Exception(ex.Message, ex); }`, however, food for thought: if you're throwing a new Exception with all the same information as the original - why are you doing it? – Kyle Muir May 11 '16 at 08:44
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/111611/discussion-between-jitendra-garg-and-kyle-muir). – jitendragarg May 11 '16 at 08:58