C#idiomatic C#
ca2200fundamentals/code-analysis/quality-rules

Code analysis

CA2200: Rethrow to preserve stack details

Learn about code analysis rule CA2200: Rethrow to preserve stack details

CA2200 Usage enabled by default in .NET 10: As warning
Fix is breaking or non-breaking Non-breakingApplicable languages C# and Visual Basic

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 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception) to capture the exception in the handler and System.Runtime.ExceptionServices.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.

sample · csharpdocs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/ca2200.cssnippet1

csharp
using System;

namespace ca2200
{
    //<snippet1>
    class TestsRethrow
    {
        static void Main2200()
        {
            TestsRethrow testRethrow = new();
            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");
        }
    }
    //</snippet1>
}

sample · vbdocs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca2200-rethrow-to-preserve-stack-details_1.vb

vb
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

See also