Il livello di servizio dovrebbe catturare tutte le eccezioni dao e racchiuderle come eccezioni di servizio?


23

Ho un'app Web Spring a tre livelli: dao, servizio e controller. Un controller non chiama mai direttamente il dao, lo fa attraverso il livello di servizio. Al momento, la maggior parte delle volte se esiste 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 catturare tutte le eccezioni dao e racchiuderle come eccezioni di servizio?

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

Supponiamo che anche ServiceException sia runtime e non sia gestito. 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 avvolgerle.

Risposte:


18

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

Se il tuo livello di servizio è solo un limite architettonico tra i livelli nel tuo progetto e il client di servizio si trova nello stesso ambito di fiducia, allora è ok per rilassare le cose e lasciare che eccezioni non controllate si estendano al livello del controller o al client di servizio.

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

Un'eccezione a livello di dati non dovrebbe mai arrivare direttamente all'utente finale di un'applicazione Web . Contiene potenzialmente informazioni interne sullo schema, le query, le informazioni sul numero di riga, i nomi delle variabili o delle funzioni, ecc. Le eccezioni dell'utente finale possono essere sanificate in un'impostazione sicura.

Un client di servizio esterno non è interessato ai dettagli dell'implementazione e non può comunque gestire eccezioni non controllate, poiché si tratta di bug o problemi ambientali. Nelle applicazioni sicure, gli errori del database non sono semplicemente abbastanza sicuri da propagarsi, OracleException - ORA-01234 - ...che potrebbe essere la terza tabella inserita. Al cliente dovrebbe essere consentito di gestire tutte le eccezioni verificate / previste che è in grado di gestire e di trattare tutto il resto come una potenziale segnalazione di bug. Il contratto di servizio deve essere un'astrazione atomica, coerente e transazionale. Se non può fare nulla per l'eccezione, l'unica cosa utile rimasta è darti una segnalazione di bug. Hai già la possibilità di registrare l'eccezione, quindi perché caricare l'utente finale con i dettagli? L'app può essere monitorata in modo da conoscere già le eccezioni non controllate prima che gli utenti le segnalino.

Non è mai ok mangiare eccezioni, né sono un fan delle eccezioni verificate, ma preferisco avere un piano appropriato per la natura del prodotto complessivo.


13

No, non è necessario racchiudere le eccezioni DAO in un'applicazione Web

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

... verrà catturato da un JSP che mostra un messaggio di errore all'utente finale.

Risolvi questo problema in un unico posto invece di ritagliare l'intera base di codice.

Sei tu a controllare come viene mostrata all'utente un'eccezione non rilevata. Eccezioni non rilevate sono dovute a bug 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 servita. Non c'è niente che l'utente possa fare. Tutto quello che dovresti fare è pubblicare una pagina di errore amichevole.

NB: se ti ritrovi a scrivere un sacco di codice noioso, ad esempio, creando un sacco di blocchi catch che semplicemente avvolgono e ri-lanciano, c'è quasi sempre una soluzione migliore.


Grazie per la tua risposta. E sì, il jsp mostra un messaggio personalizzato: "Spiacenti, qualcosa è andato storto". Non mostra alcuna informazione sull'eccezione
Oscar

7

Il motivo principale per cui si dovrebbe utilizzare il wrapping delle eccezioni è impedire al codice nel livello aziendale di dover conoscere ogni possibile eccezione nel sistema . Ci sono due ragioni principali per questo:

  • Coerenza: le eccezioni dichiarate si aggregano verso la parte superiore dello stack di chiamate. Se non racchiudi le eccezioni, ma invece le trasmetti dichiarando i tuoi metodi per lanciarle, potresti finire con metodi di livello superiore che dichiarano molte diverse eccezioni. Dichiarare tutte queste eccezioni in ogni metodo di backup dello stack di chiamate diventa noioso.

  • Incapsulamento: potresti non voler che i tuoi componenti di livello superiore sappiano nulla dei componenti di livello inferiore, né delle eccezioni che generano. Ad esempio, lo scopo delle interfacce e delle implementazioni DAO è quello di sottrarre i dettagli dell'accesso ai dati dal resto dell'applicazione. Ora, se i tuoi metodi DAO generano SQLException, il codice che utilizza 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 lanciare 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ì!


3
Le implementazioni dell'APP (ad es. Hibernate) generano eccezioni non controllate. Non devono essere dichiarati o catturati.
Kevin Cline,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.