Catch clause captures a broad exception base type
ID |
vbnet.correctness.no_catch_generic_exception |
Severity |
low |
Remediation Complexity |
medium |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Error Handling |
Language |
VB.NET |
Description
Reports a Catch clause that captures Exception, SystemException or ApplicationException - qualified or not - as well as the catch-all bare Catch. Every exception in the process derives from one of these, so the clause captures failures the code was never written to handle. A clause with a When filter is not reported, because the filter narrows what the clause actually captures.
Rationale
A broad Catch clause captures far more than the failure it was written for. Along with the expected I/O or network error it also captures programming defects - NullReferenceException, InvalidCastException, ArgumentException - and framework failures such as OutOfMemoryException, then applies recovery logic that makes no sense for them. The practical effect is that real bugs are absorbed by a handler that logs a misleading message and lets the program limp on in an inconsistent state, so the defect is discovered much later and much further from its cause. It also makes the code untestable in an important way: the clause cannot distinguish an expected failure from an unexpected one, so there is no behaviour to assert.
The following code illustrates the pattern detected by this rule:
Public Sub Pull(ByVal url As String)
Try
_client.Download(url)
' FLAGGED: Catch clause captures a broad exception base type
Catch ex As Exception
_log.Error("pull failed", ex)
End Try
End Sub
Remediation
Catch the specific exception types the guarded code can actually raise - IOException, SqlException, WebException, FormatException - one Catch clause each, ordered from the most derived to the least. When a broad clause really is needed, for example at a top-level request or thread boundary that must not let the process die, narrow it with an exception filter (Catch ex As Exception When TypeOf ex Is WebException) or rethrow with a bare Throw after logging, so that unexpected exceptions still reach the code that is meant to see them.