Preserve Stack Trace
ID |
csharp.preserve_stack_trace |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
CSharp |
Tags |
reliability |
Description
Reports a throw new …Exception(…) inside a catch block that does not pass the caught
exception to the new exception. Dropping the caught exception loses the original stack trace
and makes the root cause much harder to find.
Rationale
A catch that wraps a failure in a new exception but forgets to forward the original as the
innerException throws away the entire chain that led to the failure. The exception report
then points only at the rethrow site, hiding where the problem really started.
public class Repository
{
public void Broken()
{
try
{
Query();
}
catch (DbException ex)
{
throw new RepositoryException("query failed"); // FLAW — drops ex, original trace is lost
}
}
public void Ok()
{
try
{
Query();
}
catch (DbException ex)
{
throw new RepositoryException("query failed", ex); // OK — forwards ex as the inner exception
}
}
public void OkRethrow()
{
try
{
Query();
}
catch (DbException)
{
throw; // OK — bare rethrow preserves the trace
}
}
}
Remediation
Pass the caught exception as the innerException constructor argument
(throw new RepositoryException("query failed", ex);), or use a bare throw; to rethrow the
original exception with its stack trace intact.