CA1031: Do not catch general exception types
Property | Value |
---|---|
Rule ID | CA1031 |
Title | Do not catch general exception types |
Category | Design |
Fix is breaking or non-breaking | Non-breaking |
Enabled by default in .NET 8 | No |
Cause
A general exception such as System.Exception or System.SystemException is caught in a catch
statement, or a general catch clause such as catch()
is used.
By default, this rule only flags general exception types being caught, but this is configurable.
Rule description
General exceptions should not be caught.
How to fix violations
To fix a violation of this rule, catch a more specific exception, or rethrow the general exception as the last statement in the catch
block.
When to suppress warnings
Do not suppress a warning from this rule. Catching general exception types can hide run-time problems from the library user and can make debugging more difficult.
Note
Starting with .NET Framework 4, the common language runtime (CLR) no longer delivers corrupted state exceptions that occur in the operating system and managed code, such as access violations in Windows, to be handled by managed code. If you want to compile an application in .NET Framework 4 or later versions and maintain handling of corrupted state exceptions, you can apply the HandleProcessCorruptedStateExceptionsAttribute attribute to the method that handles the corrupted state exception.
Configure code to analyze
Use the following option to configure which parts of your codebase to run this rule on.
You can configure this option for just this rule, for all rules it applies to, or for all rules in this category (Design) that it applies to. For more information, see Code quality rule configuration options.
Disallowed exception type names
You can configure which exception types are disallowed from being caught. For example, to specify that the rule should flag catch
handlers with NullReferenceException
, add the following key-value pair to an .editorconfig file in your project:
dotnet_code_quality.CA1031.disallowed_symbol_names = NullReferenceException
Allowed type name formats in the option value (separated by |
):
- Type name only (includes all symbols with the name, regardless of the containing type or namespace)
- Fully qualified names in the symbol's documentation ID format with a
T:
prefix.
Examples:
Option value | Summary |
---|---|
dotnet_code_quality.CA1031.disallowed_symbol_names = ExceptionType |
Matches all symbols named 'ExceptionType' in the compilation. |
dotnet_code_quality.CA1031.disallowed_symbol_names = ExceptionType1|ExceptionType2 |
Matches all symbols named either 'ExceptionType1' or 'ExceptionType2' in the compilation. |
dotnet_code_quality.CA1031.disallowed_symbol_names = T:NS.ExceptionType |
Matches specific types named 'ExceptionType' with given fully qualified name. |
dotnet_code_quality.CA1031.disallowed_symbol_names = T:NS1.ExceptionType1|T:NS1.ExceptionType2 |
Matches types named 'ExceptionType1' and 'ExceptionType2' with respective fully qualified names. |
You can configure these options for just this rule, for all rules it applies to, or for all rules in this category (Design) that it applies to. For more information, see Code quality rule configuration options.
Example
The following example shows a type that violates this rule and a type that correctly implements the catch
block.
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;
}
}
}