È più sensato registrare le eccezioni in un catch-all o in una classe di eccezioni di base?

15

Sono in procinto di refactoring di un'app web abbastanza grande. Uno dei principali problemi è la gestione degli errori incoerente e sto cercando di trovare una strategia ragionevole. Ho creato un gestore di errori personalizzato, tramite set_error_handler che sostanzialmente trasforma gli errori PHP in ErrorExceptions e una classe di eccezioni di base personalizzata, che eredita direttamente da Exception .

In fase di produzione sto utilizzando un'eccezione generica, tramite set_exception_handler , e sto per aggiungere la registrazione delle eccezioni * al mix. Il mio dilemma è dove eseguire la registrazione effettiva, nella classe di eccezioni di base o nel catch-all.

Ho pensato a un paio di motivi per collegarlo al catch-all:

  • Ci sono alcune eccezioni nel codice che devono essere convertite in un figlio appropriato della classe di eccezioni di base. Fino a quel momento, non tutte le eccezioni verranno registrate.
  • In qualche modo sembra più naturale farlo nel catch-all, una classe di eccezioni di base non dovrebbe fare altro che essere solo quella. (Potrebbe trattarsi di un singolo principio di responsabilità, ma potrebbe essere solo una sensazione sbagliata)

e un motivo per accedere alla classe di eccezioni di base:

  • Attualmente il catch-all viene utilizzato solo in produzione. Sarebbe facile introdurlo nei nostri altri ambienti (sviluppo, testing) ma ciò richiederebbe alcune modifiche, poiché gli errori sono gestiti in modo diverso per ambiente, poiché sulla produzione sono tradotti in pagine di errore 404/503.

Esiste una pratica accettabile per dove registrare le eccezioni?

* La registrazione implica inizialmente la scrittura su un file di testo e potrebbe evolversi fino all'invio di e-mail per determinati tipi di eccezioni.

Alcuni chiarimenti, suggeriti dalla risposta di @ unholysampler:

Sono di fronte a un codebase 2 * 10 ^ 6 sloc, con un sacco di cose di terze parti su cui non ho controllo, e un po 'del codice che ho controllo sulle eccezioni pre-date in PHP. E c'è anche qualche codice recente schifoso, stiamo recuperando da un lungo periodo di intensa pressione in cui dovevamo praticamente smettere di pensare e appena violato.

Stiamo attivamente rifattitando per affrontare tutte le incongruenze e introdurre un approccio ragionevole alla gestione degli errori, ma ci vorrà del tempo. Sono più interessato a cosa fare fino a raggiungere il punto in cui gli errori vengono gestiti in modo appropriato. Probabilmente farò un'altra domanda su una ragionevole strategia di eccezione ad un certo punto.

La motivazione principale alla base del logging è di ricevere un'e-mail sul mio telefono ogni volta che succede qualcosa di brutto in produzione. Non mi interessa se i dump di dati diventano enormi, se lo farò farò un cron job cancellando quelli vecchi di tanto in tanto.

    
posta yannis 24.11.2011 - 05:11
fonte

2 risposte

11

In breve, l'unica volta che devi registrare l'esistenza di un'eccezione è quando lo stai gestendo.

Quando si genera un'eccezione, è perché il codice ha raggiunto uno stato in cui non può procedere correttamente. Lanciando un'eccezione, stai rappresentando un messaggio specifico per il tuo programma sull'errore che si è verificato. Non dovresti prendere un'eccezione finché non ti trovi in un punto in cui può essere gestito correttamente.

Il codice che scrivi come parte della tua applicazione principale dovrebbe essere a conoscenza dei tipi di eccezioni che possono essere lanciate e quando potrebbero essere lanciate. Se non puoi fare nulla di produttivo con un'eccezione, non prenderlo. Non registrare un'eccezione finché non viene gestita. Solo il codice di gestione sa cosa significa l'eccezione nel contesto del flusso del programma e come rispondere ad esso. Scrivere un messaggio di registro qui può avere senso qui. Se si utilizza un framework di registrazione, è possibile impostare un livello di registro per il messaggio e potenzialmente filtrarli. Funziona bene per le eccezioni che possono verificarsi, ma non sono critiche e possono essere ripristinate da pulito.

La tua eccezione è la tua eccezione, è il tuo ultimo disperato tentativo di impedire al tuo codice di causare una brutta morte. Se si è arrivati a questo punto, si registra tutto lo stato e le informazioni di errore che è possibile. Quindi fai del tuo meglio per dire chiaramente all'utente che il programma sta andando in crash prima che tutto si fermi. Il tuo obiettivo dovrebbe essere quello di non eseguire mai questo codice.

L'integrazione della registrazione nella classe base non segue le linee guida precedenti. La classe base non sa nulla sullo stato del codice. (Avere la traccia dello stack non conta perché non si sta andando a scrivere codice che prende decisioni basate sull'analisi di esso.) La classe base non può fare nulla per indicare la gravità o il modo in cui l'eccezione potrebbe essere gestita. Non vuoi enormi discariche di dati e tracce di stack ogni volta che c'è una semplice eccezione che puoi gestire e ripristinare da zero.

    
risposta data 24.11.2011 - 05:50
fonte
3

Se la tua lingua / runtime non ti permette facilmente di determinare la fonte dell'eccezione, c'è un caso per registrarlo al lancio. C ++ e alcuni motori JS non espongono il file + line o lo stack di chiamate dell'eccezione nel momento in cui lo hai catturato / ma questa informazione è disponibile nel momento in cui costruisci l'eccezione.

La nostra soluzione era di fornire un meccanismo che usasse la configurazione di runtime per abilitare la registrazione del tipo dell'eccezione insieme a uno stack economico quando si tenta di diagnosticare questi problemi.

    
risposta data 24.11.2011 - 09:37
fonte

Leggi altre domande sui tag