Avoid "throw ex;" in catch blocks

Back to articles.

When starting with exception handling it's easy to do something like this:

try
{
    // some business logic
}
catch (Exception ex)
{
    _logger.Error("Failed to save user", ex);
    throw ex;
}

The problem with throw anExceptionObject; is that .NET takes for granted that you are throwing a new exception.

For .NET these three blocks are essentially the same:

// Intended to rethrow
catch (Exception ex)
{
    _logger.Error("Failed to save user", ex);

    throw ex;
}

// Creating the exception first
catch (Exception ex)
{
    _logger.Error("Failed to save user", ex);

    var newException = new DbException("Some useful error message");
    throw newException;
}

// Creating and throwing on the same line
catch (Exception ex)
{
    _logger.Error("Failed to save user", ex);

    throw new DbException("Some useful error message");
}

If you want to continue the exception propagation you should invoke throw without an object as that instructs .NET to continue with the caught exception.

try
{
    // some business logic
}
catch (Exception ex)
{
    _logger.Error("Failed to save user", ex);

    //this
    throw;
}

Conclusion

Just use throw; when you want to let the caught exception to continue up the call stack.

throw ex will delete the existing contents in the StackTrace property.