No Catch Generic Exception
ID |
csharp.no_catch_generic_exception |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
CSharp |
Tags |
CWE:396, reliability |
Description
Reports catch blocks that catch the over-broad System.Exception (or its alias
Exception/SystemException), as well as a bare catch with no type. Catching the generic
exception swallows every error, including ones the code cannot meaningfully handle.
Rationale
A catch (Exception) traps everything — including programming errors and unexpected runtime
failures that should propagate. The result is that genuine bugs are silently absorbed, the
program limps on in an invalid state, and the failure surfaces far from its cause. Catch the
specific exception types you know how to recover from.
Two shapes narrow the handling back down to specific exceptions and are not reported, whatever the declared catch type is:
-
An exception filter,
catch (Exception ex) when (ex is IOException): thewhencondition decides what the clause actually handles, and everything else keeps propagating without ever entering the body. -
A rethrow anywhere in the body —
throw;orthrow new Wrapped(ex), including as an expression such as aswitcharm: the exception still propagates instead of being silently absorbed, so the breadth of the declared type stops mattering.
public class Importer
{
public void Broken()
{
try
{
Import();
}
catch (Exception ex) // FLAW — catches every error, hiding bugs
{
Log(ex);
}
}
public void AlsoBroken()
{
try
{
Import();
}
catch // FLAW — bare catch traps everything too
{
Ignore();
}
}
public void Filtered()
{
try
{
Import();
}
catch (Exception ex) when (ex is IOException) // OK — narrowed by the filter
{
UseDefault(ex);
}
}
public void Rethrown()
{
try
{
Import();
}
catch (Exception ex) // OK — logged, but rethrown so nothing is swallowed
{
Log(ex);
throw;
}
}
public void Ok()
{
try
{
Import();
}
catch (FileNotFoundException ex) // OK — a specific, recoverable exception type
{
UseDefault(ex);
}
}
}