Il livello di servizio deve intercettare tutte le eccezioni dao e racchiuderle come eccezioni di servizio?

18

Ho un'applicazione web Spring a tre livelli: dao, servizio e controller. Un controller non chiama mai direttamente dao, lo fa attraverso il livello di servizio. In questo momento, la maggior parte delle volte se c'è un'eccezione dao (runtime) che non viene gestita, verrà catturata da un JSP che mostra un messaggio di errore all'utente finale. Il livello di servizio dovrebbe intercettare tutte le eccezioni dao e includerle come eccezioni di servizio?

try {
   daoInstance.someDaoMethod();
} catch(DataAccessException dae) {
   throw new ServiceException("message", dae);
}

Supponiamo che ServiceException sia anche runtime e che non sia gestito neanche. C'è qualche differenza nel lanciare DataAccessException invece di ServiceException? Ho solo pensato che il livello di presentazione non dovrebbe conoscere l'eccezione di accesso ai dati. Ma non vedo il punto di catturare eccezioni irrecuperabili solo per avvolgerli.

    
posta Oscar 23.10.2014 - 00:01
fonte

3 risposte

13

Penso che un fattore importante sia chi sono i tuoi clienti di servizio.

Se il tuo livello di servizio è solo un confine architettonico tra i livelli del tuo progetto, e il client di servizio si trova nello stesso ambito di fiducia, allora è ok per rilassare le cose e lasciare che le eccezioni incontrollate diventino bolle al livello del controller, o cliente di servizio.

Tuttavia, per il codice di affissione pubblica; servizio che viene consumato da una terza parte o cliente, penso sia più pulito avvolgere eventuali eccezioni non controllate con un'eccezione orientata ai servizi, principalmente per problemi di sicurezza, in secondo luogo per un accoppiamento lento e un'astrazione pulita.

Un'eccezione del livello dati non dovrebbe mai, direttamente, renderla completamente all'utente finale di un'applicazione web . Contiene potenzialmente informazioni interne sullo schema, le query, informazioni sul numero di riga, nomi di variabili o funzioni, ecc. Le eccezioni degli utenti finali possono essere disinfettate in un ambiente sicuro.

Un client di servizio esterno non riguarda i dettagli dell'implementazione e non può comunque gestire eccezioni non controllate, in quanto sono bug o problemi ambientali. Nelle applicazioni protette, gli errori del database non sono abbastanza sicuri da propagarsi, OracleException - ORA-01234 - ... che potrebbe essere la terza tabella che è stata inserita. Il client dovrebbe essere autorizzato a gestire eventuali eccezioni verificate / previste che può gestire e trattare tutto il resto come una potenziale segnalazione di bug. Il contratto di servizio deve essere un'astrazione atomica, coerente, transazionale. Se non può fare nulla sull'eccezione, l'unica cosa utile è darti un rapporto sui bug . Hai già la possibilità di registrare l'eccezione, quindi perché caricare l'utente finale con i dettagli? La tua app può essere monitorata in modo tale che tu sappia già delle eccezioni non controllate prima che gli utenti le segnalino.

Non è mai ok per le eccezioni eat , né sono un fan delle eccezioni controllate, ma preferisco avere un piano appropriato per la natura del prodotto nel suo complesso.

    
risposta data 23.10.2014 - 01:00
fonte
9

No, non dovresti racchiudere le eccezioni DAO in un'applicazione web

C'è molto rumore nel codice a vantaggio zero. Le eccezioni DAO sono eccezioni non controllate per una buona ragione. Il codice dell'applicazione non può fare nulla di utile per recuperare da un'eccezione DAO. Il vero problema è qui:

... it'll be caught by a JSP showing an error message to the end user.

Risolvi questo problema in un unico posto invece di aggirare l'intero codice base.

Controlla come viene visualizzata un'eccezione non catturata all'utente. Le eccezioni non rilevate sono dovute a errori dell'applicazione o a un errore nel sistema sottostante. Non c'è motivo di fornire all'utente informazioni sul motivo per cui la sua richiesta non può essere fornita. Non c'è niente che l'utente possa fare. Tutto ciò che dovresti fare è pubblicare una pagina di errore amichevole.

N.B .: se ti ritrovi a scrivere un sacco di codice noioso, ad esempio, creando un sacco di blocchi catch che si limitano a avvolgere e rilanciare, c'è quasi sempre una soluzione migliore.

    
risposta data 23.10.2014 - 01:17
fonte
6

Il motivo principale per cui si usa exception wrapping è di impedire che il codice nel livello aziendale debba conoscere su ogni possibile eccezione nel sistema . Ci sono due ragioni principali per questo:

  • Coerenza: le eccezioni dichiarate si aggregano verso l'alto dello stack di chiamate. Se non si avvolgono le eccezioni, ma invece le si passano dichiarando i metodi per lanciarle, si può finire con i metodi di livello superiore che dichiarano molte eccezioni diverse. Dichiarare tutte le eccezioni in ogni metodo di backup dello stack di chiamate diventa noioso.

  • Incapsulamento: potresti non volere che i tuoi componenti di livello superiore siano a conoscenza dei componenti di livello inferiore, né delle eccezioni che generano. Ad esempio, lo scopo delle interfacce e delle implementazioni DAO è di astrarre i dettagli dell'accesso ai dati dal resto dell'applicazione. Ora, se i tuoi metodi DAO generano SQLException allora il codice che utilizza i DAO dovrà catturarli. Cosa succede se si passa a un'implementazione che legge i dati da un servizio Web anziché da un database? Quindi i metodi DAO dovranno generare sia RemoteException che SQLException. E se hai un DAO che legge i dati da un file, dovrai lanciare anche IOException. Sono tre diverse eccezioni, ognuna legata alla propria implementazione DAO.

Quindi, in breve, la risposta è sì!

    
risposta data 23.10.2014 - 00:41
fonte

Leggi altre domande sui tag