Return From Finally

ID

csharp.return_from_finally

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

CSharp

Tags

CWE:584, reliability

Description

Reports a control-flow statement (return, break, continue or goto) that abruptly exits a finally block. The abrupt exit discards any exception that was propagating from the try or catch, and overrides any value the method was about to return.

Rationale

When a finally block completes abruptly, the exception (or returned value) that was in flight is silently dropped. The original failure never reaches the caller and the bug becomes extremely hard to diagnose, because the program continues as if nothing went wrong.

public class Service
{
    public int Broken()
    {
        try
        {
            return Compute();
        }
        finally
        {
            return -1;            // FLAW — swallows any exception from Compute and overrides the result
        }
    }

    public int Ok()
    {
        try
        {
            return Compute();
        }
        finally
        {
            Cleanup();            // OK — finally only performs cleanup, control flows normally

            System.Func<int> local = () =>
            {
                return 0;         // OK — return exits the lambda, not the finally
            };
            local();
        }
    }
}

Remediation

Remove the return/break/continue/goto from the finally block. Keep cleanup logic in the finally and let the original control flow — including any propagating exception or returned value — continue unchanged.