CA1031: не перехватывайте типы общих исключений
Свойство | Значение |
---|---|
Идентификатор правила | CA1031 |
Заголовок | Не перехватывайте типы общих исключений |
Категория | Проектирование |
Исправление является критическим или не критическим | Не критическое |
Включен по умолчанию в .NET 9 | No |
Причина
В инструкции catch
перехватывается общее исключение, такое как System.Exception или System.SystemException, или используется общее предложение catch, такое как catch()
.
По умолчанию это правило помечает только общие типы исключений, но это можно настроить.
Описание правила
Общие исключения не должны перехватываться.
Устранение нарушений
Чтобы исправить нарушение этого правила, следует перехватить более конкретное исключение или повторно вызвать общее исключение в последнем операторе блока catch
.
Когда лучше отключить предупреждения
Для этого правила отключать вывод предупреждений не следует. Перехват типов общих исключений может скрыть проблемы времени выполнения пользователя библиотеки и усложнить отладку.
Примечание.
Начиная с .NET Framework 4 общеязыковая среда выполнения (CLR) больше не поставляет исключения поврежденного состояния, происходящие в операционной системе и управляемом коде, такие как нарушения прав доступа в Windows, для обработки управляемым кодом. Если вы хотите компилировать приложение в .NET Framework 4 или более поздней версии и поддерживать обработку исключений поврежденного состояния, можно применить атрибут HandleProcessCorruptedStateExceptionsAttribute к методу, обрабатывающему исключение поврежденного состояния.
Настройка кода для анализа
Используйте следующий параметр, чтобы выбрать части базы кода для применения этого правила.
Этот параметр можно настроить только для этого правила, для всех правил, к которым он применяется, или для всех правил в этой категории (конструкторе), к которым она применяется. Дополнительные сведения см. в статье Параметры конфигурации правила качества кода.
Недопустимые имена типов исключений
Вы можете настроить, какие типы исключений запрещены для перехвата. Например, чтобы указать, что правило должно помечать обработчики catch
флагом NullReferenceException
, добавьте следующую пару "ключ-значение" в файл .editorconfig в своем проекте:
dotnet_code_quality.CA1031.disallowed_symbol_names = NullReferenceException
Допустимые форматы имен типов в значении параметра (разделенные |
):
- только имя типа (включает все символы с этим именем независимо от типа и пространства имен);
- полные имена в формате идентификатора документации для символа с префиксом
T:
.
Примеры:
Значение параметра | Итоги |
---|---|
dotnet_code_quality.CA1031.disallowed_symbol_names = ExceptionType |
Соответствует всем символам с именем ExceptionType в компиляции. |
dotnet_code_quality.CA1031.disallowed_symbol_names = ExceptionType1|ExceptionType2 |
Соответствует всем символам с именем ExceptionType1 или ExceptionType2 в компиляции. |
dotnet_code_quality.CA1031.disallowed_symbol_names = T:NS.ExceptionType |
Соответствует определенным типам с именем "ExceptionType" и заданным полным именем. |
dotnet_code_quality.CA1031.disallowed_symbol_names = T:NS1.ExceptionType1|T:NS1.ExceptionType2 |
Соответствует типам с именами ExceptionType1 и ExceptionType2 с соответствующими полными именами. |
Эти параметры можно настроить только для этого правила, для всех правил, к которым она применяется, или для всех правил в этой категории (конструктор), к которым она применяется. Дополнительные сведения см. в статье Параметры конфигурации правила качества кода.
Пример
В следующем примере показан тип, который нарушает правило, и тип, который правильно реализует блок catch
.
Imports System
Imports System.IO
Namespace ca1031
' Creates two violations of the rule.
Public Class GenericExceptionsCaught
Dim inStream As FileStream
Dim outStream As FileStream
Sub New(inFile As String, outFile As String)
Try
inStream = File.Open(inFile, FileMode.Open)
Catch ex As SystemException
Console.WriteLine("Unable to open {0}.", inFile)
End Try
Try
outStream = File.Open(outFile, FileMode.Open)
Catch
Console.WriteLine("Unable to open {0}.", outFile)
End Try
End Sub
End Class
Public Class GenericExceptionsCaughtFixed
Dim inStream As FileStream
Dim outStream As FileStream
Sub New(inFile As String, outFile As String)
Try
inStream = File.Open(inFile, FileMode.Open)
' Fix the first violation by catching a specific exception.
Catch ex As FileNotFoundException
Console.WriteLine("Unable to open {0}.", inFile)
' For functionally equivalent code, also catch the
' remaining exceptions that may be thrown by File.Open
End Try
Try
outStream = File.Open(outFile, FileMode.Open)
' Fix the second violation by re-throwing the generic
' exception at the end of the catch block.
Catch
Console.WriteLine("Unable to open {0}.", outFile)
Throw
End Try
End Sub
End Class
End Namespace
// Creates two violations of the rule.
public class GenericExceptionsCaught
{
FileStream? inStream;
FileStream? outStream;
public GenericExceptionsCaught(string inFile, string outFile)
{
try
{
inStream = File.Open(inFile, FileMode.Open);
}
catch (SystemException)
{
Console.WriteLine("Unable to open {0}.", inFile);
}
try
{
outStream = File.Open(outFile, FileMode.Open);
}
catch
{
Console.WriteLine("Unable to open {0}.", outFile);
}
}
}
public class GenericExceptionsCaughtFixed
{
FileStream? inStream;
FileStream outStream;
public GenericExceptionsCaughtFixed(string inFile, string outFile)
{
try
{
inStream = File.Open(inFile, FileMode.Open);
}
// Fix the first violation by catching a specific exception.
catch (FileNotFoundException)
{
Console.WriteLine("Unable to open {0}.", inFile);
};
// For functionally equivalent code, also catch
// remaining exceptions that may be thrown by File.Open
try
{
outStream = File.Open(outFile, FileMode.Open);
}
// Fix the second violation by rethrowing the generic
// exception at the end of the catch block.
catch
{
Console.WriteLine("Unable to open {0}.", outFile);
throw;
}
}
}
Связанные правила
CA2200: следует повторно вызывать исключение для сохранения сведений о стеке