Search code examples
c#.netif-statementtry-catchefficientnet

try multi catch vs try catch by if


What are the implications of using a single catch block with type checking versus multiple catch blocks for different exception types in C#?

In C#, when handling exceptions, one can use a single catch block with type checking:

try
{
    // ...
}
catch(Exception ex)
{
    if (ex is ObjectNotFoundException)
    {
        return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
    }

    else if (ex is ModelValidationException)
    {
        return Request.CreateErrorResponse(HttpStatusCode.NotAcceptable, ex);
    }

    //... another type of exception 

    else {
        return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
    }
}

Alternatively, one can use separate catch blocks for each exception type:

try
{
    // ...
}
catch (ObjectNotFoundException ex)
{
    return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
catch (ModelValidationException ex)
{
    return Request.CreateErrorResponse(HttpStatusCode.NotAcceptable, ex);
}

//... another type of exception

catch (Exception ex)
{
    return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
} 

What are the advantages and potential pitfalls of each approach? Are there any performance considerations or best practices to consider?


Solution

  • The second approach is better since you don't want to swallow all other exceptions silently. But instead of letting the process to crash after getting uncaught exception types, it would be better to catch them, log error details and return an internal server error:

    try
    {
       // ...
    }
    catch (ObjectNotFoundException ex)
    {
        return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
    }
    catch (ModelValidationException ex)
    {
        return Request.CreateErrorResponse(HttpStatusCode.NotAcceptable, ex);
    }
    catch(Exception ex)
    {
        // log this error, so you are notified about it
        return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
    }