Se una lingua supporta intrinsecamente le eccezioni, allora è preferibile generare eccezioni e i client possono rilevare l'eccezione se non vogliono che si traduca in un errore. Infatti, i client del tuo codice si aspettano eccezioni e si imbatteranno in molti bug perché non controlleranno i valori di ritorno.
Ci sono alcuni vantaggi nell'usare le eccezioni se hai una scelta.
Messaggi
Le eccezioni contengono messaggi di errore leggibili dall'utente che possono essere utilizzati dagli sviluppatori per il debug o anche visualizzati agli utenti se lo si desidera. Se il codice che consuma non può gestire l'eccezione, può sempre registrarlo in modo che gli sviluppatori possano passare attraverso i registri senza doversi fermare ad ogni altra traccia per capire quale era il valore restituito e mapparlo in una tabella per capire quale era il vera eccezione.
Con i valori di ritorno, non è possibile fornire facilmente ulteriori informazioni. Alcune lingue supporteranno le chiamate al metodo per ottenere l'ultimo messaggio di errore, quindi questa preoccupazione è un po 'attenuata, ma ciò richiede che il chiamante effettui chiamate aggiuntive e talvolta richieda l'accesso a un "oggetto speciale" che trasporta queste informazioni.
Nel caso di messaggi di eccezione, fornisco il maggior numero possibile di contesto, come ad esempio:
A policy of name "foo" could not be retrieved for user "bar", which was referenced in user's profile.
Confrontalo con un codice di ritorno -85. Quale preferiresti?
Stack di chiamate
Le eccezioni di solito hanno anche stack di chiamate dettagliate che aiutano a eseguire il debug del codice più velocemente e più rapidamente, e possono anche essere registrati dal codice chiamante se lo si desidera. Ciò consente agli sviluppatori di individuare il problema di solito sulla linea esatta, e quindi è molto potente. Ancora una volta, confrontalo con un file di log con valori di ritorno (come -85, 101, 0, ecc.), Quale preferisci?
Approccio di bias rapido fallito
Se un metodo viene chiamato da qualche parte che non riesce, genererà un'eccezione. Il codice chiamante deve sopprimere esplicitamente l'eccezione o fallire. Ho scoperto che questo è davvero sorprendente perché durante lo sviluppo e il collaudo (e anche in produzione) il codice fallisce rapidamente, costringendo gli sviluppatori a risolverlo. Nel caso dei valori di ritorno, se viene omesso un controllo per un valore di ritorno, l'errore viene ignorato silenziosamente e l'errore emerge da qualche parte inaspettato, solitamente con un costo molto più elevato per il debug e la correzione.
Eccezioni avvolgimento e scostamento
Le eccezioni possono essere racchiuse in altre eccezioni e poi scartate se necessario. Ad esempio, il tuo codice potrebbe generare ArgumentNullException
che il codice chiamante potrebbe racchiudere all'interno di un UnableToRetrievePolicyException
poiché tale operazione non è riuscita nel codice chiamante. Mentre all'utente potrebbe essere mostrato un messaggio simile all'esempio che ho fornito sopra, alcuni codici diagnostici potrebbero scartare l'eccezione e scoprire che un ArgumentNullException
ha causato il problema, il che significa che si tratta di un errore di codifica nel codice del tuo consumatore. Questo potrebbe quindi attivare un avviso in modo che lo sviluppatore possa correggere il codice. Tali scenari avanzati non sono facili da implementare con i valori di ritorno.
Semplicità del codice
Questo è un po 'più difficile da spiegare, ma ho imparato attraverso questo codice sia con i valori di ritorno sia con le eccezioni. Il codice che è stato scritto utilizzando i valori restituiti di solito effettuava una chiamata e quindi ha una serie di controlli su quale fosse il valore restituito. In alcuni casi, chiamerebbe un altro metodo e ora avrà un'altra serie di controlli per i valori restituiti da quel metodo. Con le eccezioni, la gestione delle eccezioni è molto più semplice nella maggior parte se non in tutti i casi. Hai un blocco try / catch / finally, con il runtime che prova a fare del suo meglio per eseguire il codice nei blocchi finali per la pulizia. Anche i blocchi try / catch / finally nidificati sono relativamente più facili da seguire e gestire rispetto a nidificati se / else e valori di ritorno associati da più metodi.
Conclusione
Se la piattaforma che stai utilizzando supporta eccezioni (come Java o .NET), non dovresti assolutamente pensare che non ci sia altro modo se non lanciare eccezioni perché queste piattaforme hanno linee guida per generare eccezioni, e i tuoi clienti si aspettano così. Se stavo usando la tua libreria, non mi preoccuperei di controllare i valori di ritorno perché mi aspetto che vengano lanciate delle eccezioni, è così che è il mondo in queste piattaforme.
Tuttavia, se fosse C ++, sarebbe un po 'più difficile da determinare perché esiste già una grande base di codici con codici di ritorno, e un gran numero di sviluppatori sono sintonizzati per restituire valori in contrapposizione alle eccezioni (ad es. Windows è diffuso con HRESULT). Inoltre, in molte applicazioni, può anche essere un problema di prestazioni (o almeno percepito come).