2013-01-19 6 views
33

Ho il codice seguente:Come posso aggiungere un messaggio a un'eccezione senza perdere alcuna informazione in C#?

catch(Exception ex) 
{ 
    throw new FatalException("An error occurred while trying to load the XSLT file.", ex); 
} 

Questo, purtroppo, solo inghiotte l'eccezione. Posso risolvere questo problema nel modo seguente:

catch(Exception ex) 
{ 
    throw; 
} 

Ma mi piace ancora di comprendere il messaggio personalizzato per un aiuto con la registrazione degli eventi.

Come si aggiunge questo messaggio all'eccezione senza perdere alcuna informazione? (simboli di stack trace/debug, ecc)

+0

Aggiungere l'eccezione originale come un 'InnerException' sul' FatalException'? –

+0

È alla fine di 'lanciare nuove FatalException (" messaggio ", ex)'. – krillgar

+0

Perché vorresti fare ciò che stai mostrando? Prendi solo eccezioni con cui puoi fare qualcosa. Altrimenti lasciali gonfiare. – Mark

risposta

13

tale eccezione originale è ancora lì.

Quando fate la vostra registrazione di eccezione, l'eccezione che si riceve sarà la FatalException che hai fatto con il tuo messaggio. L'eccezione originale è ex.InnerException. È possibile continuare a scorrere InnerException finché non è nulla per ottenere tutte le informazioni dello stack, ecc

0

Insomma, non lo fanno.

Sono sicuro che si potrebbe trovare il modo di ottenere intorno a questo con qualche riflessione, ma vorrei fortemente si cautela contro questo. Va contro la progettazione originale delle eccezioni in .NET. Le eccezioni non sono solo lì per aiutare con la registrazione, ma forniscono informazioni sulla causa originale di un errore dell'applicazione.

Utilizzando la prima opzione è generalmente preferito in quanto mantiene la traccia dello stack dell'eccezione originale, ma consente di fornire informazioni aggiuntive avvolgendolo in un'eccezione separata. Nel mio codice personale, ogni volta che registro le eccezioni, la mia funzione di registrazione ricorre attraverso la proprietà InnerException per trovare ogni possibile informazione utile sull'errore.

+0

"Logging" potrebbe non essere il termine migliore da utilizzare per questo. Se stai facendo qualcosa di remoto, puoi semplicemente inviare un messaggio di posta elettronica per determinati tipi di Eccezioni quando non hai accesso a nessuna registrazione. – krillgar

46

Se hai solo bisogno di aggiungere informazioni all'eccezione originale, come un messaggio leggibile dall'utente o dettagli specifici che ti saranno utili nel rintracciare l'errore ma che non saranno utili all'utente finale, tu può fare uso della proprietà Data di Exception, che è un dizionario chiave/coppia di valori.

Questo viene ampiamente utilizzato per registrare informazioni come il report in esecuzione o il file che viene elaborato in modo che le operazioni possano determinare esattamente cosa stava accadendo al momento dell'errore. L'utente non ha bisogno di questo dettaglio poiché sta lavorando direttamente con la causa dell'errore.

Si potrebbe anche usare questo per passare un messaggio di testo normale che abbia senso per l'utente. L'unico problema è che dovrai eseguire un lavoro aggiuntivo nel tuo framework di registrazione o nell'interfaccia utente finale per estrarre i dati e renderli utili per il consumatore.

Per esempio, si potrebbe fare:

catch (Exception ex) 
{ 
    ex.Data.Add("UserMessage", "An error occurred while trying to load the XSLT file."); 
    throw; 
} 

Poi nel codice lato client, si potrebbe verificare se UserMessage esiste e, in caso affermativo, presente all'utente invece che l'eccezione:

catch (Exception ex) 
{ 
    if (ex.Data.Contains("UserMessage")) 
    { 
     MessageBox.Show(ex.Data["UserMessage"].ToString()); 
    } 
    else 
    { 
     MessageBox.Show(ex.Message); 
    } 
} 
+2

Ancora meglio sarebbe 'ex.Data [" UserMessage "] + =" Si è verificato un errore ... ";' in modo che se qualche codice di livello inferiore avesse già aggiunto un messaggio, avrebbe aggiunto il testo aggiuntivo ad esso anziché lanciare un ['ArgumentException'] (http://msdn.microsoft.com/en-us/library/system.collections.idictionary.add (v = vs.110) .aspx # ddueExceptionsToggle) – KyleMit

+0

Impressionante, grazie! Questi dati aggiuntivi vengono inoltre automaticamente aggiunti ai log di traccia .NET e, se si utilizzano chiavi univoche e messaggi descrittivi lungo tutta la catena try/catch, non ci vuole molto tempo per cercare la causa di un errore. – Joel

+0

Qual è il vantaggio di eseguire questa operazione anziché lanciare una nuova eccezione e passare l'originale come innerException in base alla risposta accettata? – ajbeaven

Problemi correlati