CA1031: Não capturar tipos de exceção geral

Property Valor
ID da regra CA1031
Título Não capturar tipos de exceção geral
Categoria Projetar
Correção interruptiva ou sem interrupção Sem interrupção
Habilitado por padrão no .NET 8 Não

Causa

Uma exceção geral, como System.Exception ou System.SystemException é capturada em uma instrução catch ou uma cláusula catch geral, como catch() é usada.

Por padrão, essa regra apenas sinaliza os tipos gerais de exceção que estão sendo capturados, mas isso é configurável.

Descrição da regra

As exceções gerais não devem ser capturadas.

Como corrigir violações

Para corrigir uma violação dessa regra, capture uma exceção mais específica ou lance novamente a exceção geral como a última instrução no bloco catch.

Quando suprimir avisos

Não suprima um aviso nessa regra. A captura de tipos de exceção gerais pode ocultar problemas de tempo de execução do usuário da biblioteca e pode dificultar a depuração.

Observação

A partir do .NET Framework 4, o Common Language Runtime (CLR) não fornece mais exceções de estado corrompido que ocorrem no sistema operacional e no código gerenciado, como violações de acesso no Windows, a serem tratadas pelo código gerenciado. Se você deseja compilar um aplicativo no .NET Framework 4, ou versões posteriores, e manter o tratamento de exceções de estado corrompido, você pode aplicar o atributo HandleProcessCorruptedStateExceptionsAttribute ao método que manipula a exceção de estado corrompido.

Configurar código para analisar

Use a opção a seguir para configurar em quais partes da base de código essa regra deve ser executada.

Você pode configurar essa opção apenas para essa regra, para todas as regras às quais ela se aplica ou para todas as regras nessa categoria (Design) às quais ela se aplica. Para obter mais informações, consulte opções de configuração de regra de qualidade de código.

Nomes de tipo de exceção não permitidos

Você pode configurar quais tipos de exceção não podem ser capturados. Por exemplo, para especificar que a regra deve sinalizar manipuladores catch com NullReferenceException, adicione o seguinte par de chave-valor a um arquivo .editorconfig em seu projeto:

dotnet_code_quality.CA1031.disallowed_symbol_names = NullReferenceException

Formatos de nome de tipo permitidos no valor da opção (separados por |):

  • Somente nome do tipo (inclui todos os símbolos com o nome, independentemente do tipo ou namespace contido)
  • Nomes totalmente qualificados no formato de ID de documentação do símbolo com um prefixo T:.

Exemplos:

Valor de opção Resumo
dotnet_code_quality.CA1031.disallowed_symbol_names = ExceptionType Corresponde a todos os símbolos chamados 'ExceptionType' na compilação.
dotnet_code_quality.CA1031.disallowed_symbol_names = ExceptionType1|ExceptionType2 Corresponde a todos os símbolos chamados 'ExceptionType1' ou 'ExceptionType2' na compilação.
dotnet_code_quality.CA1031.disallowed_symbol_names = T:NS.ExceptionType Corresponde a tipos específicos chamados 'ExceptionType' com um nome totalmente qualificado.
dotnet_code_quality.CA1031.disallowed_symbol_names = T:NS1.ExceptionType1|T:NS1.ExceptionType2 Corresponde aos tipos chamados 'ExceptionType1' e 'ExceptionType2' com os respectivos nomes totalmente qualificados.

Você pode configurar essas opções apenas para essa regra, para todas as regras às quais ela se aplica ou para todas as regras nessa categoria (Design) às quais ela se aplica. Para obter mais informações, consulte opções de configuração de regra de qualidade de código.

Exemplo

O exemplo a seguir mostra um tipo que viola essa regra e um tipo que implementa corretamente o bloco 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: Relançar para preservar detalhes da pilha