2009-04-15 7 views
6

Quali sono i tuoi pensieri su codice che assomiglia a questo:Pensieri su blocchi try-catch

public void doSomething() 
{ 
    try 
    { 
     // actual code goes here 
    } 
    catch (Exception ex) 
    { 
     throw; 
    } 
} 

Il problema che vedo è l'errore effettivo non viene gestito, appena gettare l'eccezione in un posto diverso. Trovo più difficile eseguire il debug perché non ottengo un numero di riga in cui si trova il problema reale.

Quindi la mia domanda è perché dovrebbe essere buono?

---- ---- EDIT

Dalle risposte sembra che la maggior parte delle persone stanno dicendo che è inutile fare questo senza eccezioni personalizzate o specifiche di essere catturati. Questo è quello su cui volevo i commenti, quando nessuna eccezione specifica viene catturata. Riesco a vedere il punto di fare effettivamente qualcosa con un'eccezione catturata, ma non il modo in cui questo codice è.

risposta

15

A seconda della qualità che si sta guardando, l'eccezione non viene generata in un altro luogo. "lanciare" senza un bersaglio ridisegna l'eccezione che è molto diversa dal lanciare un'eccezione. Principalmente un rethrow non ripristina la traccia dello stack.

In questo particolare esempio, la presa è inutile perché non fa nulla. L'eccezione è felicemente ripensata ed è quasi come se il tentativo/cattura non esistesse.

+0

ho visto il codice come questo prima d'ora. Normalmente è inserito durante il debug, quindi qualcuno può mettere un punto di interruzione sul "lancio". –

+0

@Joel, gotcha. Una soluzione migliore può usare VS per rompere sul lancio. Ma non è così sottile come potrebbe essere :( – JaredPar

+0

Il vantaggio rispetto a un punto di interruzione è che è possibile registrare i dettagli di un errore non critico durante i test unitari che spesso è molto utile! –

0

Ho visto istanze in cui eccezioni generiche vengono catturate in questo modo e quindi reimballate in un oggetto di eccezione personalizzato.

La differenza tra ciò e quello che stai dicendo è che quegli oggetti personalizzati di eccezione contengono ULTERIORI informazioni sull'eccezione effettiva che si è verificata, non meno.

3

Penso che la costruzione dovrebbe essere utilizzata per gestire le eccezioni che sai che verranno lanciate all'interno del codice; se viene sollevata un'altra eccezione, quindi basta rethrow.

Prendere in considerazione il lancio ; è diverso da lancio ex;

throw ex troncherà lo stack sul nuovo punto di lancio, perdendo preziose informazioni sull'eccezione.

public void doSomething() 
{ 
    try 
    { 
     // actual code goes here 
    } 
    catch (EspecificException ex) 
    { 
     HandleException(ex); 
    } 
    catch (Exception ex) 
    { 
     throw; 
    } 
} 
+1

Nel tuo esempio il catch (Exception ex) non è necessario. Semplicemente non gestire Exception avrà lo stesso effetto. –

0

Beh per cominciare mi piacerebbe semplicemente fare

catch 
{ 
    throw; 
} 

ma in fondo se si stesse intrappolando più tipi di eccezioni che potrebbe voler gestire alcuni a livello locale e gli altri backup dello stack.

ad es.

catch(SQLException sex) //haha 
{ 
    DoStuff(sex); 
} 
catch 
{ 
    throw; 
} 
1

fare qualcosa del genere è abbastanza priva di senso, e in generale cerco di non andare giù per la strada di fare le cose senza senso;)

Per la maggior parte, credo a prendere specifici tipi di eccezioni sai come gestire, anche se questo significa solo creare la tua eccezione con più informazioni e usare l'eccezione catturata come InnerException.

0

Dipende da cosa intendi per "sembra così" e se non c'è nient'altro nel blocco catch ma in un rethrow ...se è così, il tentativo di cattura è inutile, tranne che, come dici tu, per offuscare dove si è verificata l'eccezione. Ma se hai bisogno di fare qualcosa proprio lì, dove si è verificato l'errore, ma desideri gestire l'eccezione furthur in cima allo stack, questo potrebbe essere appropriato. Ma poi, la cattura sarebbe per l'eccezione specifica siete Handl, ING, non per alcuna eccezione

3

Non sarebbe, idealmente il blocco catch sarebbe fare un po 'la gestione, e quindi rigenerare, ad esempio,

try 
{ 
    //do something 
} 
catch (Exception ex) 
{ 
    DoSomething(ex); //handle the exception 
    throw; 
} 

Ovviamente il rilancio sarà utile se si desidera eseguire ulteriori operazioni nei livelli superiori del codice.

1

A volte questo è appropriato, quando si gestirà l'eccezione più in alto nello stack di chiamate. Tuttavia, dovresti fare qualcosa in quel catch catch diverso dal semplice re-throw perché abbia senso, ad es. registrare l'errore:

public void doSomething() 
{ 
    try 
    { 
     // actual code goes here 
    } 
    catch (Exception ex) 
    { 
     LogException (ex); // Log error... 
     throw; 
    } 
} 
0

Non credo che sarebbe utile ripensare l'errore. A meno che non ti interessi davvero dell'errore, in primo luogo.

Penso che sarebbe meglio fare qualcosa in realtà.

È possibile controllare lo MSDN Exception Handling Guide.