Поделиться через


CA1031: не перехватывайте типы общих исключений

TypeName

DoNotCatchGeneralExceptionTypes

CheckId

CA1031

Категория

Microsoft.Design

Критическое изменение

Не критическое

Причина

Общее исключение, такое как System.Exception или System.SystemException, перехватывается в операторе catch, либо используется общее предложение catch, такое как catch().

Описание правила

Общие исключения не должны перехватываться.

Устранение нарушений

Чтобы устранить нарушение данного правила, перехватывайте более конкретные исключения или повторно создавайте общее исключение как последний оператор в блоке catch.

Отключение предупреждений

Для этого правила отключать вывод предупреждений не следует. Перехватывание общих типов исключений может скрыть проблемы времени выполнения от пользователя библиотеки и усложнить процесс отладки.

Примечание

Начиная с .NET Framework 4, общеязыковая среда выполнения (CLR) не обеспечивает исключений поврежденного состояния, возникающих в операционной системе и управляемом коде, например нарушений прав доступа в Windows; они обрабатываться с помощью управляемого кода. Если необходимо компилировать приложение в .NET Framework 4или более поздней версии и обрабатывать исключения в поврежденном состоянии, можно применить атрибут HandleProcessCorruptedStateExceptionsAttribute к методу, обрабатывающему исключения поврежденного состояния.

Пример

В следующем примере показан тип, нарушающий данное правило, и тип, в котором правильно реализован блок catch.

Imports System
Imports System.IO

Namespace DesignLibrary

    ' 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)
            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
using System;
using System.IO;

namespace DesignLibrary
{
    // 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 e)
            {
                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 e)
            {
                Console.WriteLine("Unable to open {0}.", inFile);
            }

            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;
            }
        }
    }
}
using namespace System;
using namespace System::IO;

namespace DesignLibrary
{
    // Creates two violations of the rule.
    public ref class GenericExceptionsCaught
    {
        FileStream^ inStream;
        FileStream^ outStream;

    public:
        GenericExceptionsCaught(String^ inFile, String^ outFile)
        {
            try
            {
                inStream = File::Open(inFile, FileMode::Open);
            }
            catch(SystemException^ e)
            {
                Console::WriteLine("Unable to open {0}.", inFile);
            }

            try
            {
                outStream = File::Open(outFile, FileMode::Open);
            }
            catch(Exception^ e)
            {
                Console::WriteLine("Unable to open {0}.", outFile);
            }
        }
    };

    public ref 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^ e)
            {
                Console::WriteLine("Unable to open {0}.", inFile);
            }

            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(Exception^ e)
            {
                Console::WriteLine("Unable to open {0}.", outFile);
                throw;
            }
        }
    };
}

Связанные правила

CA2200: следует повторно вызывать исключение для сохранения сведений о стеке