2014-08-29 10 views
8

Sto lavorando a un sistema legacy che presenta un'eccezione personalizzata che viene utilizzata con gosh-frickity-ovunque. È stato ispirato dalla classe ServletException, che diceva "bene ogni volta che hai un'eccezione nel tuo servlet, ti consigliamo di lanciare questo ServletException".Creazione di un'eccezione controllata a RuntimeException

Con l'evolversi del sistema (oltre 10 anni) si è verificato un sistema più affidabile di rilevamento delle eccezioni a un livello superiore e non è più necessario avvolgere tutte le eccezioni in questa eccezione personalizzata. (Si potrebbe obiettare che non lo è mai stato, ma questa è un'altra storia: è un'app stabile, quindi tendo a non lamentarmi troppo !!), ma non li rifatteremo tutti in una volta, lentamente nel tempo.

Tuttavia, una cosa che renderebbe le cose più semplici andando avanti sarebbe se l'eccezione personalizzata fosse un'eccezione di runtime invece di un'eccezione controllata. In questo modo non avremmo bisogno di catturarlo esplicitamente ovunque, e il codice legacy che non è stato ancora rifattorizzato continuerà semplicemente a lanciare allo stesso modo in cui lanciare un'eccezione di puntatore nullo se si verifica uno.

La mia domanda è ... Quali sono gli effetti collaterali dell'osservazione di un'eccezione verificata e di un'eccezione di runtime?

Non riesco a pensare a nessuno, a parte gli avvertimenti per le verifiche e le dichiarazioni inutili, ma sarebbe bello ricevere informazioni da qualcuno che è stato in precedenza su questa strada.

+2

Uso eccellente di "frode ovunque" – Gareth

+3

È un'arma elegante di un'epoca più civilizzata. – corsiKa

+0

Come te, non posso davvero pensare a nessun effetto collaterale a questo nell'immediato. A lungo termine, potrebbe essere necessario pensare a quale gestione deve accadere se questa eccezione viene propagata lungo tutta la catena dello stack. – ControlAltDel

risposta

2

Cambiare un'eccezione controllata in una non controllata ha un effetto pratico molto piccolo sul codice esistente, funzionante, ma è necessario fare attenzione alla possibilità che da qualche parte nel codice si catch (RuntimeException ...). Tali catture non intercettano la tua eccezione personalizzata ora, ma lo farebbero se lo rendessi deselezionato.

Si potrebbero anche incorrere in problemi se si fa qualcosa di riflessivo relativo ai metodi che generano quell'eccezione (che apparentemente è la maggior parte di essi).

+0

Per fortuna facciamo pochissima riflessione. Un po 'di popolazione di fagioli, ma questo è tutto. Per quanto riguarda la cattura di RuntimeException, è un buon punto: ho fatto una ricerca in base al codice e ho trovato 7 istanze e sono tutte chiare. O prendono anche l'eccezione personalizzata o hanno lo stesso comportamento. Questo è un buon punto, tuttavia, potrebbe causare un diverso percorso di esecuzione. – corsiKa

0

Qualcosa del genere è successo su un vecchio modulo di un'app che dovevo mantenere. L'unico problema che traduce le eccezioni in runtime è che potresti perdere la granularità, ma questo dipende esclusivamente da te.

Ad esempio, abbiamo avuto una tonnellata di codice come questo negli strati più profondi:

catch(IOException e){  
    Throwables.propagate(e); 
} 

Abbiamo usato quel modello sbadatamente tutto quello strato e, quando abbiamo bisogno di controllare la causa eccezione, abbiamo sempre avuto per ottenere la causa dell'eccezione e che ha fatto molti piatti negli strati più alti. Ad oggi credo sia meglio creare una buona gerarchia di classi di eccezioni non controllate per preservare la granularità. per esempio.

catch(IOException e){ 
    throw new FileNotCreatedException(e); 
} 

E con questo si può intercettare l'eccezione facilmente in altri strati e dividere gli errori e le ricadute facilmente:

catch(FileNotCreatedException e){ 
    notifyError(e); 
} catch(NoMoreStorageException e){ 
    releaseSomeStorage(); 
    retryOperation(); 
} 
+0

Poiché la persona sta mantenendo lo stesso nome di classe, non sono sicuro di come si applica questa risposta. – JustinKSU

+0

In realtà acquisiamo granularità man mano che eliminiamo l'eccezione personalizzata che avvolge tutto e sempre più eccezioni che descrivono effettivamente qual è il problema. – corsiKa

0

Qui ci sono alcuni che mi vengono in mente

  • eccezioni runtime potrebbe potenzialmente andare a un livello in cui non hai intenzione di andare.
    • ex: un servlet ---> Servizio ---> DAO. Le eccezioni di runtime generate da DAO correlate alle interazioni del database potrebbero potenzialmente arrivare su Servlet.La chiara separazione dei livelli in cui ogni livello gestisce tutte le eccezioni (controllato/runtime) ai suoi punti di ingresso può garantire che ciò non avvenga.
  • Le eccezioni di runtime possono lasciare il sistema in uno stato incoerente.
    • es: se il diagramma di sequenza appare come Classe A -> Classe B ---> Classe C e Classe B1 se viene iniettato tra B e C, pertanto Classe A ---> Classe B ---> Classe B1 ---> Classe C quindi nessuna delle Class A, B, B1 sarebbe a conoscenza del fatto che potrebbe dover effettuare una pulizia quando questa eccezione di runtime si verifica in Classe C. In realtà ciò può potenzialmente influire sulla semantica di qualsiasi iniezione di dipendenza.

Come regola empirica generale, a mio parere:

  • Usa controllata eccezioni quando si "aspetta" l'eccezione come parte di un normale flusso di controllo e sa come gestirlo. Es .: la convalida di una regola aziendale dice che il saldo del conto deve essere maggiore dell'importo debito di almeno 100.
  • Usa eccezioni non controllate quando "non ti aspetti" l'eccezione come parte di un normale flusso di controllo quindi non avere mezzi di gestione tuttavia sai che "qualche classe" all'interno del tuo "livello" lo gestirà per garantire una degradazione graduale ex: la connessione DB persa sarebbe stata gestita dalla classe di classe del livello "servizio".
  • Non utilizzare mai l'errore. Solo JRE ha motivi per generare errori.
+0

Ironia della sorte, lo scenario che descrivi per il primo potenziale problema è esattamente il motivo per cui vogliamo sostituirlo. In questo momento, tutte le eccezioni vengono fondamentalmente incapsulate e appena generate in un filtro che controlla l'eccezione personalizzata. Mi piacerebbe mantenere le eccezioni ai livelli inferiori, se possibile. Ma vedo come potrebbe accadere ciò che descrivi se non stesse già succedendo! :) – corsiKa

Problemi correlati