Search code examples
c#exceptiontry-catchrethrow

Rethrowing an exception in C#


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. :/


Solution

  • 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;
    }