miércoles, octubre 30, 2013

Estrategia a seguir para el manejo de excepciones (Exception handling strategy)

En esta entrada copio el post http://stackoverflow.com/questions/14973642/how-using-try-catch-for-exception-handling-is-best-practice tal cual por parecerme muy interesante:

[...]

My exception handling strategy is :
  • To catch all unhandled exceptions by hooking to the Application.ThreadException event, then decide :
    • For a UI application: to pop it to the user with an apology message (winforms)
    • For a Service or a Console application: log it to a file (service or console)
Then I always enclose every piece of code that is run externally in try/catch :
  • All events fired by the Winforms infrastructure (Load, Click, SelectedChanged...)
  • All events fired by third party components
Then I enclose in 'try/catch'
  • All the operations that I know might not work all the time (IO operations, calculations with a potential zero division...). In such a case, I throw a new ApplicationException("custom message", innerException) to keep track of what really happened
Additionally, I try my best to sort exceptions correctly. There are exceptions which:
  • need to be shown to the user immediately
  • require some extra processing to put things together when they happen to avoid cascading problems (ie: put .EndUpdate in the finally section during a TreeView fill)
  • the user does not care, but it is important to know what happened. So I always log them:
    • In the event log
    • or in a .log file on the disk
It is a good practice to design some static methods to handle exceptions in the application top level error handlers.
I also force myself to try to:
  • Remember ALL exceptions are bubbled up to the top level. It is not necessary to put exception handlers everywhere.
  • Reusable or deep called functions does not need to display or log exceptions : they are eigher bubbled up automatically or rethrown with some custom messages in my exception handlers.
So finally :
Bad:
// DON'T DO, THIS IS BAD
try
{
    ...
}
catch 
{
   // only air...
}
Useless:
// DONT'T DO, THIS IS USELESS
try
{
    ...
}
catch(Exception ex)
{
    throw ex;
}
What I do at the top level:
// i.e When the user clicks on a button
try
{
    ...
}
catch(Exception ex)
{
    ex.Log(ex); // Log exception
    // ex.LogAndDisplay(ex); // Log exception, then show it to the user with apologies...
}
What I do in some called functions:
// Calculation module
try
{
    ...
}
catch(Exception ex)
{
    // Add useful information to the exception
    throw new ApplicationException("Something wrong happened in the calculation module :", ex);
}

// IO module
try
{
    ...
}
catch(Exception ex)
{
    throw new ApplicationException(string.Format("I cannot write the file {0} to {1}", fileName, directoryName), ex);
}
There is a lot to do with exception handling (Custom Exceptions) but thoses rules I try to keep in mind are enough for the simple applications I do.


No hay comentarios:

Publicar un comentario