CA1031: No capturar los tipos de excepción general

Propiedad Value
Identificador de la regla CA1031
Título No capturar los tipos de excepción general
Categoría Diseño
La corrección es problemática o no problemática Poco problemático
Habilitado de forma predeterminada en .NET 8 No

Causa

Una excepción general, como System.Exception o System.SystemException, se captura en una instrucción catch, o bien se usa una cláusula de captura general como catch().

De forma predeterminada, esta regla solo marca los tipos de excepción generales que se capturan, pero es configurable.

Descripción de la regla

No se deben capturar excepciones generales.

Cómo corregir infracciones

Para corregir una infracción a esta regla, capture una excepción más específica o vuelva a producir la excepción general como la última instrucción del bloque catch.

Cuándo suprimir las advertencias

No suprima las advertencias de esta regla. La captura de los tipos de excepción generales puede ocultar problemas en tiempo de ejecución del usuario de la biblioteca y puede dificultar la depuración.

Nota

A partir de .NET Framework 4, Common Language Runtime (CLR) ya no proporciona excepciones de estado dañado que se producen en el sistema operativo y el código administrado, como infracciones de acceso en Windows, para que las controle el código administrado. Si quiere compilar una aplicación en .NET Framework 4 o versiones posteriores y mantener el control de las excepciones de estado dañado, puede aplicar el atributo HandleProcessCorruptedStateExceptionsAttribute al método que controla la excepción de estado dañado.

Configuración del código para analizar

Use la opción siguiente para configurar en qué partes del código base ejecutar esta regla.

Puede configurar esta opción solo para esta regla, para todas las reglas a las que se aplica o para todas las reglas de esta categoría (Diseño) a las que se aplica. Para más información, vea Opciones de configuración de reglas de calidad de código.

Nombres de tipo de excepción no permitidos

Puede configurar los tipos de excepción que no se permite capturar. Por ejemplo, para especificar que la regla debe marcar los controladores catch con NullReferenceException, agregue el siguiente par clave-valor a un archivo .editorconfig en el proyecto:

dotnet_code_quality.CA1031.disallowed_symbol_names = NullReferenceException

Formatos de nombre de tipo permitidos en el valor de opción (separados por |):

  • Solo nombre de tipo (incluye todos los símbolos con el nombre, con independencia del tipo contenedor o el espacio de nombres).
  • Nombres completos en el formato de identificador de documentación del símbolo, con un prefijo T:.

Ejemplos:

Valor de la opción Resumen
dotnet_code_quality.CA1031.disallowed_symbol_names = ExceptionType Coincide con todos los símbolos denominados "ExceptionType" de la compilación.
dotnet_code_quality.CA1031.disallowed_symbol_names = ExceptionType1|ExceptionType2 Coincide con todos los símbolos denominados "ExceptionType1" o "ExceptionType2" de la compilación.
dotnet_code_quality.CA1031.disallowed_symbol_names = T:NS.ExceptionType Coincide con tipos específicos denominados "ExceptionType" con el nombre completo especificado
dotnet_code_quality.CA1031.disallowed_symbol_names = T:NS1.ExceptionType1|T:NS1.ExceptionType2 Coincide con tipos denominados "ExceptionType1" y "ExceptionType2" con los nombres completos correspondientes.

Puede configurar estas opciones solo para esta regla, para todas las reglas a las que se aplica o para todas las reglas de esta categoría (Diseño) a las que se aplica. Para más información, vea Opciones de configuración de reglas de calidad de código.

Ejemplo

En el ejemplo siguiente se muestra un tipo que infringe esta regla y un tipo que implementa correctamente el bloque 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: Reiniciar para mantener los detalles de la pila