Бөлісу құралы:


CA2200: повторно генерируйте исключение для сохранения сведений о стеке

Свойство Значение
Идентификатор правила CA2200
Заголовок Повторно перебрасывайте исключения, чтобы сохранить сведения стека
Категория Использование
Исправление является критическим или не критическим неразрывный
Включен по умолчанию в .NET 10 Как предупреждение
Применимые языки C# и Visual Basic

Причина

В операторе throw исключение повторно выбрасывается и явно указывается.

Описание правила

При возникновении исключения часть информации в нем представляет собой трассировку стека. Трассировка стека — это список иерархии вызовов методов, который начинается с метода, вызывающего исключение, и завершается методом, перехватывающим исключение. Если исключение перебрасывается, указав исключение в throw инструкции, трассировка стека перезапускается в текущем методе, а список вызовов методов между исходным методом, который вызвал исключение, и текущим методом теряется. Для сохранения исходных данных трассировки стека с исключением следует использовать оператор throw без указания исключения.

Если вы выполняете повторный выброс исключения из другого места, отличного от обработчика (catch блок), используйте ExceptionDispatchInfo.Capture(Exception) для фиксации исключения в обработчике и ExceptionDispatchInfo.Throw() при необходимости его повторного выброса.

Дополнительные сведения см. в разделе "Запись и повторное создание исключений".

Устранение нарушений

Чтобы устранить нарушение этого правила, повторно выбросьте это исключение без его явного указания.

Когда лучше отключить предупреждения

Для этого правила отключать вывод предупреждений не следует.

Пример

В следующем примере показан метод, CatchAndRethrowExplicitlyкоторый нарушает правило и метод, CatchAndRethrowImplicitlyкоторый удовлетворяет правилу.

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");
    }
}
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

См. также