CA1031 : Ne pas intercepter des types d'exception générale

Propriété Value
Identificateur de la règle CA1031
Titre Ne pas intercepter des types d'exception générale
Catégorie Conception
Le correctif est cassant ou non cassant Sans rupture
Activé par défaut dans .NET 8 Non

Cause

Une exception générale, comme System.Exception ou System.SystemException, est interceptée dans une instruction catch, ou une clause catch générale comme catch() est utilisée.

Par défaut, cette règle signale uniquement les types d’exceptions généraux qui sont interceptés, mais cela est configurable.

Description de la règle

Les exceptions générales ne doivent pas être interceptées.

Comment corriger les violations

Pour corriger une violation de cette règle, interceptez une exception plus spécifique ou relancez l’exception générale en tant que dernière instruction du bloc catch.

Quand supprimer les avertissements

Ne supprimez aucun avertissement de cette règle. L’interception des types d’exceptions généraux peut masquer les problèmes au runtime de l’utilisateur de la bibliothèque et rendre le débogage plus difficile.

Remarque

À compter de .NET Framework 4, le Common Language Runtime (CLR) ne fournit plus d’exceptions d’état altéré, qui se produisent dans le système d’exploitation et le code managé, comme les violations d’accès dans Windows, et qui sont gérées avec du code managé. Si vous souhaitez compiler une application dans .NET Framework 4 ou versions ultérieures et gérer les exceptions d’état altéré, vous pouvez appliquer l’attribut HandleProcessCorruptedStateExceptionsAttribute à la méthode qui gère l’exception d’état altéré.

Configurer le code à analyser

Utilisez l’option suivante pour configurer les parties de votre codebase sur lesquelles exécuter cette règle.

Vous pouvez configurer cette option pour cette règle uniquement, pour toutes les règles auxquelles elle s’applique ou pour toutes les règles de cette catégorie (Conception) auxquelles elle s’applique. Pour plus d’informations, consultez Options de configuration des règles de qualité du code.

Noms de types d’exception non autorisés

Vous pouvez configurer les types d’exceptions à ne pas intercepter. Par exemple, pour spécifier que la règle doit marquer les descripteurs catch avec NullReferenceException, ajoutez la paire clé-valeur suivante à un fichier .editorconfig dans votre projet :

dotnet_code_quality.CA1031.disallowed_symbol_names = NullReferenceException

Formats de nom de type autorisés dans la valeur d’option (séparés par |) :

  • Nom du type uniquement (inclut tous les symboles avec le nom, quel que soit le type ou l’espace de noms qui les contient)
  • Noms qualifiés complets au format d’ID de documentation du symbole, avec un préfixe T:.

Exemples :

Valeur d'option Récapitulatif
dotnet_code_quality.CA1031.disallowed_symbol_names = ExceptionType Correspond à tous les symboles nommés « ExceptionType » dans la compilation.
dotnet_code_quality.CA1031.disallowed_symbol_names = ExceptionType1|ExceptionType2 Correspond à tous les symboles nommés « ExceptionType1 » ou « ExceptionType2 » dans la compilation.
dotnet_code_quality.CA1031.disallowed_symbol_names = T:NS.ExceptionType Correspond à des types spécifiques nommés « ExceptionType » avec un nom complet donné.
dotnet_code_quality.CA1031.disallowed_symbol_names = T:NS1.ExceptionType1|T:NS1.ExceptionType2 Correspond aux types nommés « ExceptionType1 » et « ExceptionType2 » avec les noms complets respectifs.

Vous pouvez configurer ces options pour cette règle uniquement, pour toutes les règles auxquelles elles s’appliquent ou pour toutes les règles de cette catégorie (Conception) auxquelles elles s’appliquent. Pour plus d’informations, consultez Options de configuration des règles de qualité du code.

Exemple

L’exemple suivant montre un type qui enfreint cette règle et un type qui implémente correctement le bloc 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 : Levez à nouveau une exception pour conserver les détails de la pile