2010-08-05 19 views
5

Ho ereditato il codice nel nostro progetto che assomiglia a questo. È un metodo in una classe.lanciare un'eccezione nel blocco try anziché bloccare il blocco?

protected override bool Load() 
{ 
    DataAccess.SomeEntity record; 

    try 
    { 
     record = _repository.Get(t => t.ID.Equals(ID)); 

     if (record == null) 
     { 
      throw new InvalidOperationException("failed to initialize the object."); 
     } 
     else 
     { 
      this.ID = record.ID; 
      // this.OtherProperty = record.SomeProperty; 
      // etc 
     } 
    } 
    catch (Exception) 
    { 
     throw; 
    } 

    return true; 
} 

Se dunque io chiamo questo metodo Load dal mio livello di interfaccia utente, probabilmente sarei voglio avere un blocco try catch per catturare qualsiasi eccezione causata dalla mancata caricare l'istanza, per esempio InvalidOperationException, ma il codice sopra riportato mi sembra sbagliato.

L'eccezione InvalidOperationException non può essere ingerita dalla dichiarazione catch? tale dichiarazione di cattura colga anche potenziali problemi con _repository.Get, oltre a potenziali problemi con l'impostazione delle proprietà se il record è valido.

Ho pensato che dovrei forse ristrutturarlo aggiungendo ulteriori istruzioni catch try per gestire le operazioni Get e le operazioni di configurazione delle proprietà separatamente, o aggiungere più blocchi catch gestendo diverse eccezioni, ma ho chiesto a un collega e lui ha suggerito che il try catch è irrilevante in questo caso, e deve essere rimosso completamente, lasciando le cose come:

protected override bool Load() 
{ 
    DataAccess.SomeEntity record; 

    record = _repository.Get(t => t.ID.Equals(ID)); 

    if (record == null) 
    { 
     throw new InvalidOperationException("failed to initialize the object."); 
    } 
    else 
    { 
     this.ID = record.ID; 
     // this.OtherProperty = record.SomeProperty; 
     // etc 
    } 

    return true; 
} 

vorrei un po 'un secondo parere, ho appena iniziato a prendere un interesse per la gestione delle eccezioni, quindi mi piacerebbe assicurati che lo sto facendo nel modo giusto secondo le migliori pratiche.

+0

Il tuo collega aveva ragione. Entrambe le versioni fanno lo stesso, quindi perché non avere meno codice? –

+0

Vorrei suggerire che * throw * è stato lasciato lì dal debugging - con quel pezzo di codice puoi piazzare un breakpoint sul * throw *, e poi ispezionare l'eccezione (usando '$ exception' nella finestra immediata). Fare ciò è utile quando non si è ancora sicuri esattamente di cosa potrebbe uscire da lì, e come gli altri poster hanno detto che non ha alcun effetto altrimenti. – slugster

risposta

0

Se si stanno rilevando eccezioni nel metodo di chiamata (Ithink), è necessario il rilevare solo eccezioni che si prevede. Se l'eccezione è un problema per Load(), quindi lancia una nuova eccezione al metodo chiamante, con informazioni migliori sull'eccezione.

+1

Definisci "le eccezioni che * puoi gestire *". Ci sono un sacco di eccezioni che puoi aspettarti, ma, a questo punto del codice, non puoi fare nulla di utile. – Richard

+0

Sono d'accordo :) –

0

Eccellente! Sei decisamente sulla buona strada. L'implementazione precedente non faceva altro che rilanciare eccezioni che non sono necessarie. Dovresti gestire solo eccezioni specifiche che stai anticipando nel livello aziendale, altrimenti lascia che salgano naturalmente allo stack di chiamate fino al livello dell'interfaccia utente.

Come best practice, solo ri-generare eccezioni quando si desidera aggiungere alcune informazioni di debug aggiuntive, nel qual caso è necessario definire un eccezione personalizzata

6

Quando si esegue questa operazione:

catch (Exception) 
{ 
    throw; 
} 

Essenzialmente non stai gestendo l'eccezione. Ciò non significa tuttavia che lo stai ignorando. L'istruzione throw propagherà l'eccezione nello stack. Per motivi di codice pulito e leggibile, il tuo esempio finale è molto meglio.

+0

Davvero l'unica ragione per avere questo codice (senza nulla prima del 'lancio') è quello di collegare un debugger (piuttosto che Debug | Exception che è globale). – Richard

+0

Rileva solo eccezioni che si sa devono essere catturate. Generalmente non considero alcun blocco di prova, a meno che non sappia esattamente perché ne ho bisogno in una situazione particolare. Lasciare la gestione degli errori disattivata fino a quando non ne hai assolutamente bisogno: inizia con un unico gestore di errori globale nel punto più alto dell'applicazione - se questo è asp.net puoi agganciare l'evento di errore dell'applicazione e registrare gli errori lì, ma il mio punto è don aggiungere i blocchi catch try a meno che non si sappia il motivo per cui li si aggiunge e si scrive codice che gestisce i casi di errore non li intrappola. Inoltre, non è necessario rilanciare un errore se si rimuove il catch di prova – Doug

0

L'eccezione sarà essere catturati dalla dichiarazione catch ma dal momento che ha una dichiarazione throw, sarà generare l'eccezione di nuovo fuori. Questo ha lo stesso effetto che se tu non avessi un try/catch, quindi il tuo collega ha ragione nel suggerire di lasciarlo fuori.

Non c'è molto altro da aggiungere codice di gestione delle eccezioni se in realtà non si gestisce l'eccezione in alcun modo.

0

Sono d'accordo con il tuo collega, dovresti solo prendere delle eccezioni che sai essere obbligate a catturare. Generalmente non considero alcun blocco di prova, a meno che non sappia esattamente perché ne ho bisogno in una situazione particolare. Questo perché tendi a nascondere i veri bug nel tuo codice se metti semplicemente il blocco catch su tutto. Lascia la gestione degli errori disattivata fino a quando non ne hai assolutamente bisogno: inizia con un unico gestore di errori globale nel punto più alto dell'applicazione, se questo è asp.rete è possibile agganciare l'evento di errore dell'applicazione e registrare gli errori lì, ma il mio punto è non aggiungere blocchi di catch try a meno che non si sappia perché aggiungerli e scrivere codice che gestisca i casi di errore non li intrappoli.

Divertiti!

Problemi correlati