Udostępnij przez


CA1031: Nie przechwytuj szeroko definiowanych wyjątków

Nieruchomość Wartość
Identyfikator reguły CA1031
Tytuł Nie przechwytuj typów wyjątków ogólnych
Kategoria Projekt
Poprawka jest zawodna lub niezawodna Niezgodność
Domyślnie włączone na platformie .NET 10 Nie.

Przyczyna

Ogólny wyjątek, taki jak System.Exception lub System.SystemException, jest przechwytywany w instrukcji catch, lub używana jest ogólna klauzula przechwytywania, taka jak catch().

Domyślnie ta reguła flaguje tylko przechwycone ogólne typy wyjątków, ale jest to możliwe do skonfigurowania.

Opis reguły

Ogólne wyjątki nie powinny być przechwytywane.

Jak naprawić naruszenia

Aby naprawić naruszenie tej reguły, przechwyć bardziej szczegółowy wyjątek lub jako ostatnią instrukcję w bloku catch ponownie zgłoś ogólny wyjątek.

Kiedy pomijać ostrzeżenia

Nie pomijaj ostrzeżeń dla tej reguły. Przechwytywanie ogólnych typów wyjątków może ukryć problemy środowiska uruchomieniowego od użytkownika biblioteki i może utrudnić debugowanie.

Uwaga

Począwszy od programu .NET Framework 4, środowisko uruchomieniowe języka wspólnego (CLR) nie dostarcza już uszkodzonych wyjątków stanu występujących w systemie operacyjnym i zarządzanym kodzie, takich jak naruszenia dostępu w systemie Windows, które mają być obsługiwane przez kod zarządzany. Jeśli chcesz skompilować aplikację w programie .NET Framework 4 lub nowszym i zachować obsługę uszkodzonych wyjątków stanu, możesz zastosować HandleProcessCorruptedStateExceptionsAttribute atrybut do metody obsługującej uszkodzony wyjątek stanu.

Konfigurowanie kodu do analizowania

Użyj następującej opcji, aby skonfigurować, na które części bazy kodu ta reguła ma być stosowana.

Tę opcję można skonfigurować tylko dla tej reguły, dla wszystkich reguł, do których ma ona zastosowanie, lub dla wszystkich reguł w tej kategorii (Projekt), których dotyczy. Aby uzyskać więcej informacji, zobacz Opcje konfiguracji reguły jakości kodu.

Niedozwolone nazwy typów wyjątków

Można skonfigurować typy wyjątków, które nie mogą być przechwytywane. Aby na przykład określić, że reguła powinna oznaczać catch obsługujące za pomocą NullReferenceException, dodaj następującą parę klucz-wartość do pliku .editorconfig w projekcie:

dotnet_code_quality.CA1031.disallowed_symbol_names = NullReferenceException

Dozwolone formaty nazw typów w wartości opcji (oddzielone przez |):

  • Tylko nazwa typu (zawiera wszystkie symbole o nazwie, niezależnie od typu zawierającego lub przestrzeni nazw)
  • W pełni kwalifikowane nazwy w formacie identyfikatora dokumentacji symbolu z prefiksem T:.

Przykłady:

Wartość opcji Podsumowanie
dotnet_code_quality.CA1031.disallowed_symbol_names = ExceptionType Pasuje do wszystkich symboli o nazwie "ExceptionType" w kompilacji.
dotnet_code_quality.CA1031.disallowed_symbol_names = ExceptionType1|ExceptionType2 Pasuje do wszystkich symboli o nazwie "ExceptionType1" lub "ExceptionType2" w kompilacji.
dotnet_code_quality.CA1031.disallowed_symbol_names = T:NS.ExceptionType Dopasowuje określone typy o nazwie "ExceptionType" z podaną w pełni kwalifikowaną nazwą.
dotnet_code_quality.CA1031.disallowed_symbol_names = T:NS1.ExceptionType1|T:NS1.ExceptionType2 Dopasowuje typy o nazwach „ExceptionType1” i „ExceptionType2” z ich w pełni kwalifikowanymi nazwami.

Możesz skonfigurować te opcje tylko dla tej reguły, dla wszystkich reguł, do których mają zastosowanie, lub dla wszystkich reguł w tej kategorii (Design), do których mają zastosowanie. Aby uzyskać więcej informacji, zobacz Opcje konfiguracji reguły jakości kodu.

Przykład

W poniższym przykładzie pokazano typ naruszający tę regułę i typ, który poprawnie implementuje catch blok.

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
{
    private readonly FileStream? _inStream;
    private readonly FileStream? _outStream;

    public GenericExceptionsCaught(string inFile, string outFile)
    {
        try
        {
            _inStream = File.Open(inFile, FileMode.Open);
        }
        catch (SystemException)
        {
            Console.WriteLine($"Unable to open {inFile}.");
        }

        try
        {
            _outStream = File.Open(outFile, FileMode.Open);
        }
        catch
        {
            Console.WriteLine($"Unable to open {outFile}.");
        }
    }
}

public class GenericExceptionsCaughtFixed
{
    private readonly FileStream? _inStream;
    private readonly 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 {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 {outFile}.");
            throw;
        }
    }
}

CA2200: Ponownie zgłoś wyjątek, aby zachować szczegóły stosu