Throwing exceptions the right way

Use ReSharp­er? Notice every time ReSharp­er sees code like this:

catch (Exception ex)
{
    // some exception handling, or logging here
    throw ex;
}

it com­plains, and tells you to get rid of the ex for the rea­son ‘Excep­tion rethrow pos­si­bly intend­ed’?

The rea­son ReSharp­er is warn­ing you about an ‘excep­tion rethrow’ is that when you rethrow an excep­tion it replaces the stack trace of the orig­i­nal excep­tion with the cur­rent loca­tion. So if you print the stack trace fur­ther up the code you will not be able to see the state­ment which caused the excep­tion in the first place!

For this rea­son, you should ALWAYS use this instead:

catch (Exception ex)
{
    // exception handling
    throw;
}

Handling multiple exceptions

Fur­ther on excep­tion han­dling, if your code might throw mul­ti­ple types of excep­tions and you want to han­dle the excep­tions dif­fer­ent­ly then you can build up a hier­ar­chy of catch claus­es from the most spe­cif­ic (SqlEx­cep­tion e.g.) at the top, to the least spe­cif­ic (Excep­tion) at the bot­tom like this:

try
{
    // do something that can might throw an exception
}
catch (SqlException sqlEx)
{
    // retry on timeout or deadlock for example?
}
catch (Exception ex)
{
    // handle more generic exception
}
finally
{
    // put any clean up operations here
}

It’s worth not­ing that, if you are catch­ing the more gen­er­al excep­tions fur­ther up the chain your excep­tion han­dling code for more spe­cif­ic types of excep­tion low­er down the list will nev­er be called! But for­tu­nate­ly tools like ReSharp­er will warn you first :-)

Anoth­er thing you might want to con­sid­er is to wrap the built-in excep­tion types into a cus­tom Excep­tion type and maybe use an enum to cat­e­gorise the dif­fer­ent excep­tions into well defined types that your appli­ca­tion under­stands (e.g. Server­Error, Feed­Er­ror, Data­baseEr­ror, etc.).

In the case of WCF ser­vices, you can also spec­i­fy fault con­tracts for each oper­a­tion and in your catch claus­es on the serv­er side wrap all excep­tions into faults so when excep­tions hap­pen they don’t fault your chan­nel. For more on WCF error han­dling and fault con­ver­sion, have a look at this arti­cle.