CA1031: 不要捕捉一般例外類型

屬性
規則識別碼 CA1031
職稱 不要捕獲一般例外狀況類型
類別 設計
修正是造成中斷還是不中斷 不中斷
在 .NET 10 中預設啟用
適用語言 C# 與 Visual Basic

原因

會在catch語句中攔截一般例外狀況,例如System.ExceptionSystem.SystemException,或者使用一般 catch 子句,例如catch()

根據預設,此規則只會標記要捕捉的一般例外狀況類型,但這是可以配置

規則描述

不應該攔截一般例外狀況。

如何修正違規

若要解決此規則的違反,請捕捉更具體的例外狀況,或將一般例外狀況作為區塊中的catch最後一句重新擲回。

隱藏警告的時機

請勿隱藏此規則的警告。 捕捉一般例外類型可以隱藏執行時問題,讓函式庫使用者無法察覺,並使除錯變得更困難。

注意

從 .NET Framework 4 開始,Common Language Runtime (CLR) 不再提供操作系統和 Managed 程式代碼中發生的損毀狀態例外狀況,例如 Windows 中的存取違規,以由 Managed 程式代碼處理。 如果您想要在 .NET Framework 4 或更新版本中編譯應用程式,並維護損毀狀態例外狀況的處理,您可以將 屬性套用 HandleProcessCorruptedStateExceptionsAttribute 至處理損毀狀態例外狀況的方法。

設定程式代碼以分析

使用下列選項來設定程式代碼基底要執行此規則的部分。

您可以只針對此規則、對其適用的所有規則,或對應用於此類別(設計)的所有規則,設定此選項。 如需詳細資訊,請參閱 程式代碼品質規則組態選項

不允許的例外狀況類型名稱

您可以設定不允許攔截哪些例外狀況類型。 例如,若要指定規則應該使用 catch來標幟NullReferenceException處理程式,請將下列機碼/值組新增至專案中的 .editorconfig 檔案:

dotnet_code_quality.CA1031.disallowed_symbol_names = NullReferenceException

選項值中允許的類型名稱格式(以 |分隔):

  • 輸入類型名稱即可(不論其所在類型或命名空間,將會包含名稱的所有符號)
  • 符號的 文件識別碼格式 的完整名稱,前面加上 T: 前綴。

範例:

選項值 摘要
dotnet_code_quality.CA1031.disallowed_symbol_names = ExceptionType 比對編譯中名為「ExceptionType」的所有符號。
dotnet_code_quality.CA1031.disallowed_symbol_names = ExceptionType1|ExceptionType2 在編譯過程中比對名為 'ExceptionType1' 或 'ExceptionType2' 的所有符號。
dotnet_code_quality.CA1031.disallowed_symbol_names = T:NS.ExceptionType 比對名為 『ExceptionType』 的特定類型,並指定完整名稱。
dotnet_code_quality.CA1031.disallowed_symbol_names = T:NS1.ExceptionType1|T:NS1.ExceptionType2 比對名稱為 'ExceptionType1' 和 'ExceptionType2' 的型別及其各自的完整識別名稱。

您可以只針對此規則、套用至的所有規則,或套用至此類別的所有規則(設計)設定這些選項。 如需詳細資訊,請參閱 程式代碼品質規則組態選項

範例

下列範例顯示一個違反此規則的類型,以及另一個正確實現 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
{
    private readonly FileStream? _inStream;
    private readonly FileStream? _outStream;

    public GenericExceptionsCaught(string inFile, string outFile)
    {
        try
        {
            _inStream = File.Open(inFile, FileMode.Open);
        }
        catch (SystemException)
        {
            Console.WriteLine($"Unable to open {inFile}.");
        }

        try
        {
            _outStream = File.Open(outFile, FileMode.Open);
        }
        catch
        {
            Console.WriteLine($"Unable to open {outFile}.");
        }
    }
}

public class GenericExceptionsCaughtFixed
{
    private readonly FileStream? _inStream;
    private readonly 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 {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 {outFile}.");
            throw;
        }
    }
}

CA2200:重擲以保留堆疊詳細資料