Usa le eccezioni per cose eccezionali, le cose che non puoi ragionevolmente aspettarti di incontrare troppo spesso, cose che indicano che qualcosa va storto. Ad esempio, se la rete non funziona, è una cosa eccezionale per un server Web. Se il database non è disponibile, significa che qualcosa non va. Se manca il file di configurazione, probabilmente significa che l'utente ha sbagliato.
Non utilizzare le eccezioni per gestire il codice errato. Per verificare la correttezza del codice, è necessario utilizzare le asserzioni o, in .NET Framework 4 e versioni successive, i contratti di codice (che sostituiscono le asserzioni e presentano funzionalità aggiuntive e particolarmente preziose).
Non usare eccezioni in casi non eccezionali. Il fatto che l'utente, quando gli viene chiesto di inserire un numero, abbia inserito "cane" non è così eccezionale da meritare un'eccezione.
Fai attenzione quando scegli i tipi di eccezioni. Crea i tuoi tipi quando necessario. Scegli con cura l'eredità, tenendo presente che catturare i genitori catturerà anche i bambini. Mai throw Exception
.
Non utilizzare i codici di ritorno per errori. I codici di errore possono essere facilmente mascherati, ignorati, dimenticati. Se si verifica un errore, gestirlo o propagarlo nello stack superiore.
Nei casi in cui un metodo dovrebbe restituire un errore e l'errore non è eccezionale, utilizzare enum, mai numeri di errore. Esempio:
// Note that the operation fails pretty often, since it deals with the servers which are
// frequently unavailable, and the ones which send garbage instead of the actual data.
private LoadOperationResult LoadProductsFromWeb()
{
...
}
Il significato di LoadOperationResult.ServerUnavailable
, LoadOperationResult.ParsingError
ecc. È molto più esplicito di, diciamo, ricordare che il codice 12 significa che il server è inattivo e il codice 13 - che i dati non possono essere analizzati.
Utilizzare i codici di errore quando si riferiscono a quelli comuni, noti a tutti gli sviluppatori che lavorano nel dominio specifico. Ad esempio, non reinventare un valore enum per HTTP 404 Not Found o HTTP 500 Internal Server Error.
Attenzione ai booleani. Prima o poi, vorrai sapere non solo se un metodo specifico è riuscito o meno, ma perché. Eccezioni ed enumerazioni sono molto più potenti per questo.
Non cogliere ogni eccezione (a meno che tu non sia in cima allo stack). Se ricevi un'eccezione, dovresti essere pronto a gestirla. Catturare tutto sta dimostrando che non ti importa se il tuo codice viene eseguito correttamente. Questo potrebbe risolvere il problema "Non voglio cercare subito come risolvere questo problema", ma prima o poi ti farà del male.
In C #, non ricodificare mai eccezioni come questa:
catch (SomeException ex)
{
...
throw ex;
}
perché stai rompendo lo stack. Fallo invece:
catch (SomeException)
{
...
throw;
}
Fare uno sforzo quando si scrivono messaggi di eccezione. Quante volte ho visto qualcosa di simile throw Exception("wrong data")
o throw Exception("shouldn't call this method in this context")
. Altri sviluppatori, incluso te stesso sei mesi dopo, non avrebbero idea di quali dati siano errati e perché o perché non dovremmo chiamare un metodo in un contesto, né quale contesto precisamente.
Non mostrare messaggi di eccezione all'utente. Non sono previsti per la gente comune e spesso sono persino illeggibili per gli sviluppatori stessi.
Non localizzare i messaggi di eccezione. Cercare la documentazione per un messaggio localizzato è estenuante e inutile: ogni messaggio dovrebbe essere solo in inglese e inglese.
Non concentrarti esclusivamente su eccezioni ed errori: anche i log sono estremamente importanti.
In .NET, non dimenticare di includere eccezioni nella documentazione XML del metodo:
/// <exception cref="MyException">Description of the exception</exception>
Includere eccezioni nella documentazione XML rende le cose molto più facili per la persona che sta utilizzando la libreria. Non c'è niente di più fastidioso che cercare di indovinare quale eccezione potrebbe essere generata da un metodo e perché.
In questo senso¹, la gestione delle eccezioni Java fornisce un approccio più rigoroso e migliore. Ti costringe a gestire le eccezioni potenzialmente generate dai metodi chiamati o a dichiarare nel tuo metodo che può generare eccezioni che non gestisci, rendendo le cose particolarmente trasparenti.