Try Catch Finally Not All Code Paths Return a Value

The following code should in an ideal circumstance execute a scalar sql command:

    public object AsScalar()
    {
        SqlCommand cmd = CreateSqlCommand();
        try
        {

            cmd.Connection.Open();
            return cmd.ExecuteScalar();
        }
        catch (Exception exc)
        {
            log.Error("Exception caught for command: "+_sql, exc);
        }
        finally
        {
            Done(cmd);
        }
    }

However I receive the following error from Visual Studio 2010:

not all code paths return a value   

I thought that in a try-catch-finally it will always execute the finally statement regardless of whether an exception had been caught or not, but it seems that is not the case.

Why does adding the catch clause cause this error when try-finally works without issue?

Jon Skeet
people
quotationmark

With the catch clause, if the exception is thrown you're catching it and then it's not propagating out of the method... so execution will get to the end of your try/catch/finally block, reach the end of the method, and you won't be returning anything - oops!

When you only had a try/finally statement, you'd either get to the return statement, or an exception would be thrown which would be propagated out of the method - both of which are fine.

If you want to rethrow the exception, you could use:

catch (Exception exc)
{
    log.Error("Exception caught for command: "+_sql, exc);
    throw;
}

That will fix the compile-time error, as now there's no way of getting to the end of the method without returning a value or an exception being propagated. However, I'd generally discourage the "log/throw/log/throw" chain going up the stack - it's usually cleaner to just log at the top level, with whatever's ultimately catching the exception. If you want to add more context, you could either add it to the existing exception (there's the Exception.Data property, although it's rarely used in my experience) or wrap this exception in another one.

people

See more on this question at Stackoverflow