CA1031: Nie przechwytuj wyjątków typów ogólnych

Właściwości Wartość
Identyfikator reguły CA1031
Tytuł Nie przechwytuj typów wyjątków ogólnych
Kategoria Projekt
Poprawka powodująca niezgodność lub niezgodność Niezgodność
Domyślnie włączone na platformie .NET 8 Nie.

Przyczyna

Ogólny wyjątek, taki jak System.Exception lub System.SystemException jest przechwycony w catch instrukcji, lub jest używana ogólna klauzula catch, 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 ponownie wywróć ogólny wyjątek jako ostatnią instrukcję catch w bloku.

Kiedy pomijać ostrzeżenia

Nie pomijaj ostrzeżeń dla tej reguły. Przechwytywanie ogólnych typów wyjątków może ukrywać problemy z czasem wykonywania 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ć, które części bazy kodu mają być uruchamiane w tej regule.

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 są przechwytywane. Aby na przykład określić, że reguła powinna flagować catch programy obsługi za pomocą NullReferenceExceptionpolecenia , 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 prefiksemT:.

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 Pasuje do określonych typów o nazwie "ExceptionType" z daną w pełni kwalifikowaną nazwą.
dotnet_code_quality.CA1031.disallowed_symbol_names = T:NS1.ExceptionType1|T:NS1.ExceptionType2 Pasuje do typów o nazwach "ExceptionType1" i "ExceptionType2" z odpowiednimi w pełni kwalifikowanymi nazwami.

Możesz skonfigurować te opcje tylko dla tej reguły, dla wszystkich reguł, do których ma ona zastosowanie, lub dla wszystkich reguł w tej kategorii (Projekt), do których ma ona 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
{
    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: Zgłoś ponownie wyjątek, aby zachować szczegóły stosu