Richiama la stessa eccezione per fornire maggiori informazioni

7

È una buona pratica riproporre la stessa eccezione per fornire informazioni più specifiche? Ad esempio:

var sitemap = "a string containing an XML document";
try {
   // throw InvalidXmlException if the document is not well formed
   parse(sitemap);
} catch (InvalidXmlException e) {
   throw new InvalidXmlException("The sitemap is not well formed: " + e.getMessage());
}
    
posta Cequiel 01.04.2015 - 22:04
fonte

5 risposte

22

Fornire più informazioni sul contesto è sempre buono. Ma c'è un problema nel codice che volevo segnalare (forse un problema con l'API - la classe di eccezione sottostante). Non stai passando la causa principale. Non aggiungere e.getMessage () potrebbe essere ridondante. Invece imposta la causa alla radice in questo modo

catch(SameExceptionClass e) {
    throw new SameExceptionClass("Some more Details", e);
}

Quando questa eccezione viene stampata conterrà il tuo messaggio da e e i dettagli aggiuntivi che hai appena aggiunto. Se la classe di eccezione non accetta la causa principale, considera l'aggiunta di un costruttore che può accettarlo. La mancata fornitura della causa root porta a problemi relativi alle eccezioni "inghiottite", in cui non si conosce il punto reale in cui si è verificata l'eccezione originale.

Ma sì, fallo SOLO se ritieni di aggiungere più valore o più informazioni di contesto nella tua nuova eccezione.

    
risposta data 01.04.2015 - 22:53
fonte
3

Generalmente la regola per le eccezioni è, non creare un nuovo tipo di eccezione e non rilanciare, a meno che tu non sia sicuro che il chiamante sarà in grado di fare qualcosa di diverso con le nuove informazioni fornite ( cioè stai fornendo più informazioni, come un messaggio di errore migliore, o fornisci informazioni da recuperare).

    
risposta data 01.04.2015 - 22:22
fonte
2

C'è qualcos'altro qui che nessuno ha ancora menzionato: Abstraction . Forse ancora più importante, leaky astrazioni?

Ha senso lasciare che DataService lanci un'eccezione IO o database? Direi di no, perché "perde" l'implementazione sottostante al codice client. Il tuo FooController non dovrebbe importare se DataService sta parlando a un database o un file system. Tutto ciò che deve sapere è che i dati richiesti non possono essere recuperati. Quindi sì. Rilanciare l'eccezione e aggiungere le informazioni aggiuntive (conservando correttamente la traccia dello stack) al livello appropriato di astrazione. Nell'esempio che ho fornito, a livello di DataService .

    
risposta data 01.04.2015 - 23:21
fonte
1

Dipende

Se il tuo metodo sta facendo qualcosa che sarà visibile all'utente finale, la sicurezza diventa un problema. Non devi mai restituire eccezioni di basso livello all'utente sui sistemi distribuiti.

L'istruzione catch () dovrebbe incapsulare l'errore di basso livello e scriverlo solo su un meccanismo di registrazione (più) sicuro. Uno che è facilmente accessibile solo dal personale di supporto, non al pubblico in generale.

Quindi, crea e lancia un nuovo tipo di eccezione generico che informa l'utente abbastanza da poterlo segnalare in modo intelligente, ma non fornisce loro le chiavi per il regno.

Per tutte le altre eccezioni, generalmente è meglio catturare l'eccezione nel punto in cui può essere effettivamente gestita.

Ad esempio: se si dispone di una classe business che chiama diverse classi di dati, la business class potrebbe essere la soluzione migliore per gestire effettivamente eventuali eccezioni di dati (ovvero dare loro contesto nel grande schema delle cose). Quindi, non prendere affatto nelle classi di dati.

Il tuo chilometraggio può variare.

    
risposta data 06.04.2015 - 22:29
fonte
0

Spesso la traccia dello stack in un'eccezione non ha alcun valore e in tali casi non viene fatto alcun danno nel generare una nuova eccezione.

Se non sai cosa ti è successo, ovviamente mantieni tutti i dati che puoi per scopi di debug. Tuttavia, nel codice ben scritto ci saranno alcune eccezioni di questo tipo, la maggior parte delle eccezioni sarà dovuta al fatto che il programma è vittima di forze esterne. Se sai qual è la forza esterna che ha causato il problema, la cosa più informativa da fare è dire all'utente che

Se sai che non è riuscito a trovare il lavoro che hai appena detto di lavorare, perché ti importa di cosa stava eseguendo? L'informazione importante è che il lavoro non è stato trovato. (Ho in mente un caso in cui ogni lavoro ha una directory con alcuni megabyte di dati che non sono nel database.)

    
risposta data 06.04.2015 - 22:40
fonte

Leggi altre domande sui tag