CA2200: Rethrow to preserve stack details
Property | Value |
---|---|
Rule ID | CA2200 |
Title | Rethrow to preserve stack details |
Category | Usage |
Fix is breaking or non-breaking | Non-breaking |
Enabled by default in .NET 9 | As warning |
Cause
An exception is rethrown and the exception is explicitly specified in the throw
statement.
Rule description
Once an exception is thrown, part of the information it carries is the stack trace. The stack trace is a list of the method call hierarchy that starts with the method that throws the exception and ends with the method that catches the exception. If an exception is rethrown by specifying the exception in the throw
statement, the stack trace is restarted at the current method and the list of method calls between the original method that threw the exception and the current method is lost. To keep the original stack trace information with the exception, use the throw
statement without specifying the exception.
If you're rethrowing the exception from somewhere other than the handler (catch
block), use ExceptionDispatchInfo.Capture(Exception) to capture the exception in the handler and ExceptionDispatchInfo.Throw() when you want to rethrow it.
For more information, see Capture and rethrow exceptions properly.
How to fix violations
To fix a violation of this rule, rethrow the exception without specifying the exception explicitly.
When to suppress warnings
Do not suppress a warning from this rule.
Example
The following example shows a method, CatchAndRethrowExplicitly
, that violates the rule and a method, CatchAndRethrowImplicitly
, that satisfies the rule.
class TestsRethrow
{
static void Main2200()
{
TestsRethrow testRethrow = new TestsRethrow();
testRethrow.CatchException();
}
void CatchException()
{
try
{
CatchAndRethrowExplicitly();
}
catch (ArithmeticException e)
{
Console.WriteLine($"Explicitly specified:{Environment.NewLine}{e.StackTrace}");
}
try
{
CatchAndRethrowImplicitly();
}
catch (ArithmeticException e)
{
Console.WriteLine($"{Environment.NewLine}Implicitly specified:{Environment.NewLine}{e.StackTrace}");
}
}
void CatchAndRethrowExplicitly()
{
try
{
ThrowException();
}
catch (ArithmeticException e)
{
// Violates the rule.
throw e;
}
}
void CatchAndRethrowImplicitly()
{
try
{
ThrowException();
}
catch (ArithmeticException)
{
// Satisfies the rule.
throw;
}
}
void ThrowException()
{
throw new ArithmeticException("illegal expression");
}
}
Imports System
Namespace ca2200
Class TestsRethrow
Shared Sub Main2200()
Dim testRethrow As New TestsRethrow()
testRethrow.CatchException()
End Sub
Sub CatchException()
Try
CatchAndRethrowExplicitly()
Catch e As ArithmeticException
Console.WriteLine("Explicitly specified:{0}{1}",
Environment.NewLine, e.StackTrace)
End Try
Try
CatchAndRethrowImplicitly()
Catch e As ArithmeticException
Console.WriteLine("{0}Implicitly specified:{0}{1}",
Environment.NewLine, e.StackTrace)
End Try
End Sub
Sub CatchAndRethrowExplicitly()
Try
ThrowException()
Catch e As ArithmeticException
' Violates the rule.
Throw e
End Try
End Sub
Sub CatchAndRethrowImplicitly()
Try
ThrowException()
Catch e As ArithmeticException
' Satisfies the rule.
Throw
End Try
End Sub
Sub ThrowException()
Throw New ArithmeticException("illegal expression")
End Sub
End Class
End Namespace