Come implementare la gestione degli errori [chiuso]


13

Anche se ho programmato a livello professionale per alcuni anni, non capisco ancora completamente la gestione degli errori. Sebbene le mie applicazioni funzionino correttamente, la gestione degli errori non è implementata a livello professionale ed è un mix and match di una serie di tecniche.

Non c'è struttura dietro la mia gestione degli errori. Mi piacerebbe imparare e capire come è implementato a livello professionale. Questa è un'area in cui mi manca la conoscenza.

Quando devo usare un'eccezione e quando devo restituire uno stato di successo, per essere verificato nel flusso logico? È corretto combinare l'eccezione e restituire uno stato?

Scrivo principalmente in C #.


2
Perché votare male? Sto ponendo una domanda seria sull'implementazione della gestione degli errori e su come è stata eseguita. Se questo non è il posto migliore per porre una simile domanda tra i programmatori, allora dov'è? Mi dà davvero fastidio quando le persone non votano tali domande perché non c'è nessun altro posto dove porre una domanda del genere. È forse l'unico posto sul web in cui otterrò una risposta affidabile e possibili risorse. Quindi, invece di votare una domanda che gli altri faranno sicuramente Google, non sarebbe più facile rispondere?
James Jeffery,

6
La tua domanda è molto ampia. Forse potresti restringere il campo di applicazione mettendo in relazione esempi specifici di come non sei riuscito a raggiungere i tuoi obiettivi di programmazione.
Andyz Smith,

Ci sono molti articoli sul web sulla gestione degli errori: prova questo: msdn.microsoft.com/en-us/library/seyhszts.aspx
Nir Kornfeld

Risposte:


25
  1. 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.

  2. 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).

  3. 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.

  4. 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.

  5. 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.

  6. 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.ParsingErrorecc. È 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.

  7. 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.

  8. 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.

  9. 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.

  10. In C #, non ricodificare mai eccezioni come questa:

    catch (SomeException ex)
    {
        ...
        throw ex;
    }
    

    perché stai rompendo lo stack. Fallo invece:

    catch (SomeException)
    {
        ...
        throw;
    }
    
  11. 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.

  12. Non mostrare messaggi di eccezione all'utente. Non sono previsti per la gente comune e spesso sono persino illeggibili per gli sviluppatori stessi.

  13. 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.

  14. Non concentrarti esclusivamente su eccezioni ed errori: anche i log sono estremamente importanti.

  15. 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.


¹ Detto questo, trovo Java la distinzione tra eccezioni ed errori piuttosto inutili e confuse, dato che il linguaggio ha verificato e deselezionato le eccezioni. Fortunatamente, .NET Framework ha solo eccezioni e nessun errore.


Ho imparato un po 'di citazione da questo, posso chiedere da dove proviene la lista? Esperienza personale o sul sito? Ad ogni modo un lavoro eccezionale (hehe capito?).
Shelby115,

@ Shelby115: l'elenco viene, in ordine: Stack Stack, esperienza personale e codice completo di Steve Mcconnell.
Arseni Mourzenko,

Grazie @MainMa che è un'ottima risposta! Possedevo il codice completo quando ero all'università, ma qualcuno l'ha rubato. Non sono riuscito a leggerlo.
James Jeffery,

@JamesJeffery: poi prendi in prestito la seconda edizione in una biblioteca o acquistane una: è uno dei rari libri sullo sviluppo che vale assolutamente la pena.
Arseni Mourzenko,

@MainMa Appena ordinato da Amazon, grazie: DI possiede anche Clean Code e si è completamente dimenticato del capitolo 7.
James Jeffery,

1

Penso che l'elenco di MainMa sia molto completo. Aggiungerò solo alcuni dei miei:

  1. Leggi l' articolo di Eric Lippert su come categorizza le eccezioni. Particolarmente importante è il suo punto di non catturare le eccezioni che sono in realtà bug nel tuo codice. Correggi invece il codice!
  2. Se sai che può verificarsi un'eccezione E puoi fare qualcosa al riguardo, gestiscila, ma limita l'ambito del tentativo di individuare e rilevare l'eccezione specifica che ti aspetti. Cioè, non farlo:

public void Foo() {
    try {
        //get input from use
        //do calculations
        //open file
    }
    catch (Exception ex) {
       //handle exception
    }
}

Invece fai questo:

public void Foo() {
    //get input from use
    //do calculations
    try {
        //open file
    }
    catch (FileOpenException ex) {
       //handle exception
    }
}
  • Non utilizzare eccezioni per il flusso di controllo. Ad esempio, non generare ClientNotFoundException in una finestra di dialogo di ricerca (un client non trovato non è eccezionale in questa situazione) e aspettarsi che il codice chiamante mostri un messaggio "Nessun risultato trovato" quando ciò accade.

  • Non ingoiare eccezioni!

  • Tieni presente che gestire veramente un'eccezione può significare solo 3 cose:

    1. Riprovare l'operazione. Valido solo se il problema è temporaneo.
    2. Prova un'alternativa.
    3. Avvisare qualcuno del problema. Valido solo se la notifica è utilizzabile, nel senso che l'utente può fare qualcosa al riguardo.

    Se nessuna di queste opzioni si applica, probabilmente non dovresti prendere quell'eccezione. È necessario registrarlo, tuttavia, quindi annullare l'operazione o arrestare. Ovviamente ciò dipende dalle vostre esigenze in termini di correttezza e robustezza.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.