Catch Variable Reassigned

ID

csharp.catch_variable_reassigned

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Code Smell

Language

CSharp

Tags

best-practice, reliability

Description

Reports assignments to the caught exception variable inside a catch block, for example ex = new InvalidOperationException("wrapped"). Overwriting the variable that holds the caught exception throws away the original exception object together with the stack trace it captured.

Rationale

The caught exception is the single most valuable piece of diagnostic information available at the point of failure. Reassigning the catch variable discards the original cause: the exception that is eventually thrown or logged no longer references where the failure actually happened. Wrapping the original exception as the innerException of a new exception keeps the full chain intact, while a bare reassignment loses it.

public void Process()
{
    try
    {
        DoWork();
    }
    catch (IOException ex)
    {
        ex = new IOException("processing failed");   // FLAW — drops the original exception
        throw ex;
    }
}

public void ProcessSafely()
{
    try
    {
        DoWork();
    }
    catch (IOException ex)
    {
        ex.Data["context"] = "processing";           // OK — keeps the same exception
        throw new IOException("processing failed", ex);  // OK — original passed as inner exception
    }
}

Remediation

Do not reassign the catch variable. To raise a more meaningful exception, create a new one and pass the caught exception as its innerException argument, for example throw new IOException("processing failed", ex);. To attach context, set members on the caught exception (ex.Data[…​]) rather than replacing it.