Un'eccezione è un errore di blocco .
Prima di tutto, la migliore pratica dovrebbe essere non gettare eccezioni per qualsiasi tipo di errore, a meno che non sia un errore di blocco .
Se l'errore sta bloccando , quindi genera l'eccezione. Una volta che l'eccezione è già stata lanciata, non è necessario nasconderla perché è eccezionale; informa l'utente a riguardo (dovresti riformattare l'intera eccezione a qualcosa di utile per l'utente nell'interfaccia utente).
Il tuo compito come sviluppatore di software è di cercare di prevenire un caso eccezionale in cui alcuni parametri o situazioni di runtime potrebbero finire in un'eccezione. Cioè, le eccezioni non devono essere disattivate, ma devono essere evitate .
Ad esempio, se sai che alcuni input interi potrebbero avere un formato non valido, usa int.TryParse
invece di int.Parse
. Ci sono molti casi in cui puoi farlo invece di dire semplicemente "se fallisce, lancia semplicemente un'eccezione".
Generare eccezioni è costoso.
Se, dopo tutto, viene generata un'eccezione, invece di scrivere l'eccezione nel registro una volta che è stata generata, una delle migliori pratiche è catturarla in un gestore di eccezioni alla prima possibilità . Per esempio:
- ASP.NET: Global.asax Application_Error
- Altri: evento AppDomain.FirstChanceException .
La mia posizione è che i tentativi / catture locali siano più adatti per la gestione di casi speciali in cui è possibile tradurre un'eccezione in un'altra o quando si desidera "disattivarla" per un caso molto, molto, molto, molto speciale (un bug di libreria generare un'eccezione non correlata che è necessario disattivare l'audio per risolvere l'intero bug).
Per il resto dei casi:
- Cerca di evitare le eccezioni.
- Se ciò non è possibile: gestori di eccezioni alla prima possibilità.
- Oppure usa un aspetto PostSharp (AOP).
Risposta a @thewhiteambit su alcuni commenti ...
@thewhiteambit ha detto:
Le eccezioni non sono errori fatali, sono eccezioni! A volte non sono nemmeno errori, ma considerarli errori fatali è completamente falsa comprensione di cosa siano le eccezioni.
Prima di tutto, come un'eccezione non può essere nemmeno un errore?
- Nessuna connessione al database => eccezione.
- Formato stringa non valido per l'analisi di un'eccezione type =>
- Cercando di analizzare JSON e mentre l'input non è in realtà un'eccezione JSON =>
- Argomento
null
mentre l'oggetto era previsto => eccezione
- Alcune librerie hanno un bug => genera un'eccezione imprevista
- C'è una connessione socket e viene disconnesso. Quindi si tenta di inviare un messaggio => eccezione
- ...
Potremmo elencare 1k casi in cui viene generata un'eccezione e, dopo tutto, uno qualsiasi dei possibili casi sarà un errore .
Un'eccezione è un errore, perché alla fine è un oggetto che raccoglie informazioni diagnostiche: ha un messaggio e succede quando qualcosa va storto.
Nessuno lancerebbe un'eccezione quando non esiste un caso eccezionale. Le eccezioni dovrebbero bloccare gli errori perché, una volta che vengono lanciate, se non si tenta di cadere nell'uso, provare / catturare e le eccezioni per implementare il flusso di controllo significano che l'applicazione / servizio interromperà l'operazione che è entrata in un caso eccezionale .
Inoltre, consiglio a tutti di verificare il paradigma fail-fast pubblicato da Martin Fowler (e scritto da Jim Shore) . È così che ho sempre capito come gestire le eccezioni, anche prima di arrivare a questo documento qualche tempo fa.
[...] considerali errori fatali è una comprensione completamente falsa di quali siano le eccezioni.
Di solito le eccezioni interrompono il flusso di operazioni e vengono gestite per convertirle in errori comprensibili all'uomo. Pertanto, sembra che un'eccezione sia in realtà un paradigma migliore per gestire i casi di errore e lavorarci su per evitare un crash completo dell'applicazione / servizio e informare l'utente / consumatore che qualcosa è andato storto.
Altre risposte alle preoccupazioni di @thewhiteambit
Ad esempio, in caso di mancata connessione al database, il programma potrebbe eccezionalmente continuare con la scrittura su un file locale e inviare le modifiche al database una volta che sarà nuovamente disponibile. Il tuo casting String-To-Number non valido potrebbe essere tentato di analizzare nuovamente con l'interpretazione lingua-locale su Exception, come quando si tenta che la lingua inglese predefinita su Parse ("1,5") non riesca e si riprovi con l'interpretazione tedesca che è completamente bene perché usiamo la virgola anziché il punto come separatore. Vedi queste eccezioni non devono nemmeno essere bloccate, hanno solo bisogno di una gestione delle eccezioni.
Se la tua app potrebbe funzionare offline senza conservare i dati nel database, non dovresti usare eccezioni , poiché l'implementazione del flusso di controllo tramite try/catch
è considerata un anti-pattern. Il lavoro offline è un possibile caso d'uso, quindi si implementa il flusso di controllo per verificare se il database è accessibile o meno, non si attende fino a quando non è raggiungibile .
L' analisi è anche un caso previsto ( non CASO ECCEZIONALE ). Se ti aspetti questo, non usi eccezioni per controllare il flusso! . Ottieni alcuni metadati dall'utente per sapere qual è la sua cultura e usi i formattatori per questo! .NET supporta anche questo e altri ambienti, e un'eccezione perché la formattazione dei numeri deve essere evitata se si prevede un uso specifico della cultura dell'applicazione / servizio .
Un'eccezione non gestita di solito diventa un errore, ma le eccezioni in sé non sono codeproject.com/Articles/15921/Not-All-Exceptions-Are-Errors
Questo articolo è solo un'opinione o un punto di vista dell'autore.
Dal momento che Wikipedia può anche essere solo l'opinione degli autori articolari, non direi che è il dogma , ma controlla cosa dice Coding per articolo di eccezione da qualche parte in alcuni paragrafi:
[...] L'uso di queste eccezioni per gestire errori specifici che si presentano per continuare il programma si chiama codifica per eccezione. Questo anti-pattern può degradare rapidamente il software in termini di prestazioni e manutenibilità.
Dice anche da qualche parte:
Utilizzo dell'eccezione errato
Spesso la codifica per eccezione può comportare ulteriori problemi nel software con un utilizzo errato dell'eccezione. Oltre a utilizzare la gestione delle eccezioni per un problema univoco, l'utilizzo errato delle eccezioni lo porta ulteriormente eseguendo il codice anche dopo che viene sollevata l'eccezione. Questo scarso metodo di programmazione ricorda il metodo goto in molti linguaggi software ma si verifica solo dopo che è stato rilevato un problema nel software.
Onestamente, credo che il software non possa essere sviluppato non prendendo sul serio i casi d'uso. Se lo sai che ...
- Il tuo database può andare offline ...
- Alcuni file possono essere bloccati ...
- Alcune formattazioni potrebbero non essere supportate ...
- La convalida di alcuni domini potrebbe non riuscire ...
- L'app dovrebbe funzionare in modalità offline ...
- qualunque sia il caso d'uso ...
... non userete eccezioni per quello . Si potrebbe sostenere questi casi d'uso utilizzando flusso di controllo regolare.
E se alcuni casi d'uso imprevisti non sono coperti, il tuo codice fallirà rapidamente, perché genererà un'eccezione . Giusto, perché un'eccezione è un caso eccezionale .
In altra parte, e, infine, a volte si copre casi eccezionali gettando le eccezioni previste , ma non gettare loro di implementare il flusso di controllo. Lo fai perché vuoi notificare ai livelli superiori che non supporti alcuni casi d'uso o che il tuo codice non funziona con alcuni argomenti o dati / proprietà dell'ambiente.