Raccomanda un modello di progettazione / approccio all'esposizione / tolleranza / recupero da errori di sistema, gestione delle eccezioni (ad es. in Java, C ++, Perl, PHP)

12

Puoi raccomandare un modello / approccio di progettazione per l'esposizione / tolleranza / recupero da errori di sistema, gestione delle eccezioni (Java, C ++, Perl, PHP)?

Alcuni errori devono essere segnalati.

Alcuni errori possono essere gestiti internamente (da un nuovo tentativo o sono irrilevanti (possono essere ignorati).

Come si struttura il codice per catturarli?

Ma tutti gli errori devono essere registrati.

Quali migliori pratiche ci sono?

E per simularli per poter testare completamente i componenti che ne sono influenzati?

Domanda specifica del linguaggio non di programmazione generale applicabile a diversi linguaggi di programmazione moderni, ma gradirebbe esempi di esempio di schemi, approcci e filosofie in Java, C ++, PHP e Perl.

(Richiesto anche in stackoverflow: link ma ho pensato che dovesse essere richiesto anche ai programmatori perché penso che i programmatori Q & A coprano problemi software / di programmazione più ampi, mentre lo stackoverflow è più relativo all'implementazione tecnica IMHO).

    
posta therobyouknow 19.09.2011 - 16:18
fonte

3 risposte

15

Fail fast è un ottimo approccio al design e forse può essere considerato come un pattern: link

Ho anche trovato una serie di principi utili:

  • Considera le eccezioni come parte dell'interfaccia per ogni funzione / modulo : ad esempio, documentali e, se necessario, se la tua lingua lo supporta, utilizza le eccezioni controllate.
  • Mai fudge un errore - se fallisce, non provare a continuare con qualche tentativo di "assumere" come procedere. Ad esempio, la gestione speciale per i casi null è spesso un odore di codice: se il metodo richiede un valore non nullo, dovrebbe generare immediatamente un'eccezione se rileva un valore Null (NullPointerException o idealmente un IllegalArgumentException più descrittivo). / li>
  • Scrivi test unitari per casi eccezionali e normali - a volte questi test possono essere difficili da configurare ma ne vale la pena quando si vuole essere certi che il sistema sia affidabile rispetto agli errori
  • Accedi al punto in cui è stato rilevato e gestito l'errore (supponendo che l'errore fosse di gravità sufficiente per essere registrato). La ragione di ciò è che implica la comprensione della causa e un approccio per gestire l'errore, in modo che tu possa rendere significativo il messaggio di log .....
  • Utilizza le eccezioni solo per condizioni / errori realmente imprevisti. Se la tua funzione "fallisce" in un modo che è effettivamente previsto (es. polling per vedere se sono disponibili più input e non ne trovi), allora dovrebbe restituire un risposta normale ("nessun input disponibile"), non lanciare un'eccezione
  • Fallisci con garbo (credito a Steven Lowe!) - ripulisci prima di terminare se possibile, in genere spostando le modifiche, eseguendo il rollback della transazione o liberando risorse in un'istruzione "finally" o equivalente. Il clean-up dovrebbe idealmente accadere allo stesso livello in cui le risorse sono state commesse per motivi di chiarezza e coerenza logica.
  • Se devi fallire, fallisci a voce alta - un'eccezione che nessuna parte del tuo codice è stata in grado di gestire (cioè percolata al livello superiore senza essere catturata + gestita) dovrebbe causare un fallimento immediato, rumoroso e visibile che indirizza la tua attenzione su di esso. In genere interrompo il programma o l'attività e scrivo un rapporto di eccezione completo su System.out.
risposta data 19.09.2011 - 17:36
fonte
5

Avendo lavorato con le eccezioni in Java e .NET E dopo aver letto un sacco di articoli su come / quando / perché catturare eccezioni, alla fine sono arrivato con i seguenti passaggi che ho attraversato nella mia testa ogni volta che vedo accadere una potenziale eccezione, o un'eccezione devo prendere (Java) ... anche se non dovesse mai accadere (sospiro ...). E sembra che funzioni, almeno per me:

  1. C'è qualcosa di utile che posso fare con quell'eccezione (tranne la registrazione)? Se la risposta è sì, scrivi il codice del workaround e se la soluzione alternativa può generare eccezioni, vai a 2:
  2. Avvolgi l'eccezione attorno a un'eccezione di runtime, lanciala, vai a 3.
  3. Nella classe di livello superiore in cui è stata avviata una possibile transazione di database / processo, rilevare l'eccezione, eseguire il rollback della transazione, rilanciare l'eccezione.
  4. Nella classe di livello superiore (che può essere quella in cui è stata avviata la transazione), registrare l'eccezione utilizzando un framework di registrazione come slf4j (abbinato a log4j per esempio) o log4net . Se possibile, invia direttamente l'e-mail all'eccezione a una lista di distribuzione composta da sviluppatori dell'applicazione.
  5. Se c'è una GUI, visualizza un messaggio di errore che indica nel modo più intuitivo che cosa ha causato il problema; non visualizzare l'eccezione / stacktrace, l'utente non si cura e non ha bisogno di sapere che era una NullPointerException.

Dovrei anche aggiungere il passaggio 0 , dove sto deliberatamente buttando quella che chiamo un'eccezione "business" (una nuova eccezione che creo estendendo la classe "Exception") quando un trattamento complesso non può essere eseguito a causa di errori nei dati, ma è noto che si verificano perché sono stati identificati come casi eccezionali durante l'analisi.

Ad eccezione della parte relativa al logging, sono pienamente d'accordo con i punti scritti da "mikera"; Devo solo aggiungere che l'eccezione dovrebbe essere loggata una sola volta .

Inoltre, i passaggi che ho elencato potrebbero essere diversi se quello che stai scrivendo è un API / Framework . Lì, il lancio di eccezioni ben progettate è obbligatorio per aiutare gli sviluppatori a comprendere i propri errori.

Per quanto riguarda il test delle eccezioni, usando gli oggetti mock dovresti essere in grado di testare quasi tutto, sia esso eccezionale o meno, a patto che le tue classi rispettino la pratica migliore di "una classe per fare una cosa". Personalmente, mi assicuro anche di contrassegnare i metodi più importanti, ma nascosti, come "protetti" anziché "privati" in modo da poterli testare senza troppi problemi. A parte questo, testare le eccezioni è semplice, basta provocare l'eccezione e "aspettarsi" che si verifichi un'eccezione catturandola. Se non ricevi un'eccezione, allora hai un errore di caso di test unitario.

    
risposta data 19.09.2011 - 18:04
fonte
0

Costruisci i tuoi oggetti nel modo giusto, non preoccuparti di fattori esterni. Se scegli di sfruttare le eccezioni, crea i tuoi oggetti generando eccezioni se non riescono a qualcosa.

Una volta che tutti gli oggetti funzionano correttamente, dovrebbe essere abbastanza facile creare una gerarchia di responsabilità pulita nella gestione degli errori.

    
risposta data 19.09.2011 - 17:28
fonte