2011-09-06 19 views
6

Voglio lanciare un'eccezione ma con messaggio personalizzato e persistono anche stacktrace. Ho attraversato vari thread.Throw exception ma persist stack trace

catch (Exception ex) 
{ 
throw; // Message is read only but stacktrace persist 
throw ex; // Message is readonly and strack trace also blows .. worst! 
throw new CustomException("My exception");// Message can be overridden but stacktrace lost 
throw new CustomException("My message",ex);// same as above. However if this constructor in exception class calls same constructor of base class then .. see below 
} 

Quando si utilizza lo scorso appraoch (con eccezione personalizzata costruttore di chiamare costruttore della classe base), in uscita sullo schermo della morte è qualcosa di simile:

**The remote server returned an error: (401) Unauthorized.** 

[WebException: The remote server returned an error: (401) Unauthorized.] 
original stack trace 

[NewException: newMessage] 
New Stack Trace 

La cosa buona è che tutto è lì sullo schermo. Ma, in cima, voglio che la mia eccezione visualizzi "nuovo messaggio" e non un messaggio originale.

Quindi riconciliare la mia domanda: COME posso visualizzare sullo schermo della morte la traccia dello stack originale ma con un messaggio di errore personalizzato?

+1

Si tratta di un servizio web di ritorno l'eccezione? – Oded

+0

Nel mio esempio è in effetti una chiamata al servizio web. Tuttavia è irrilevante in quanto l'eccezione avrebbe potuto essere qualcosa di simile a DivisionByZero o sqlException, ecc. L'idea è di far conoscere all'utente la traccia dello stack originale, ma lo sviluppatore personalizza anche il messaggio di eccezione predefinito ad uno più aiutante. – helloworld

+0

No, non è irrilevante. I framework dei servizi Web hanno le loro idee sulle eccezioni. –

risposta

8
throw new CustomException("My message",ex);// same as above (... stacktrace lost) 

La tua conclusione nei commenti è sbagliata sull'ultima. Lo stacktrace viene mantenuto nell'eccezione interna. La reportistica standard (incluso Exception.ToString()) riporterà lo stacktrace completo. Questo è quello che vedi quando ottieni il costruttore giusto. (Chiama sempre il basebo corretto!).

Ma non riconosco [WebException]. In WCF è necessario

<serviceDebug includeExceptionDetailInFaults="true"/> 

Credo proprio ambiente Web ha una funzione simile di sopprimere informazioni errore nei confronti del cliente.

3

Utilizzare il quarto approccio è come viene generalmente fatto e il modello stabilito. Non si deve confondere la gestione delle eccezioni (o il sollevamento) con il modo in cui vengono visualizzati o registrati, o qualsiasi altra cosa.

Se si ha l'uscita del l'eccezione (pescato) sotto controllo, cioè può cambiare/scrittura rispettivo codice, si può semplicemente utilizzare il metodo Exception.ToString(), che stampare l'eccezione esterno, inclusi tutti i "interni".

Nota: A volte le eccezioni interne non vengono visualizzate di proposito da un'applicazione. Ad esempio in WCF (Windows Communication Foundation) l'eccezione interna non viene nemmeno trasferita dal server al client a meno che non sia impostato IncludeExceptionDetails (via config, code, ...). Questo di solito è fatto perché l'eccezione interna è considerata un dettaglio di implementazione, che può fornire a un utente malintenzionato informazioni preziose per violare l'applicazione.

0

E la sostituzione della proprietà StackTrace?

class CustomException : Exception { 

    public CustomException(string message, Exception inner) : base(message, inner) { 
    } 

    public override string StackTrace { 
     get { 
      if (InnerException != null) { 
       return InnerException.StackTrace; 
      } 
      return base.StackTrace; 
     } 
    } 
} 
+0

grazie! Provato ... Mentre lo schermo giallo della morte veniva visualizzato, la rottura sul ritorno InnerException.Stacktrace veniva chiamata tre volte e ogni volta mostrava lo stacktrace originale. Ma strano è che mostrava ancora una nuova traccia dello stack :( – helloworld

+0

@enableDeepak: non sapeva che avrebbe fatto collassare l'universo su se stesso ... scusa :( –

0

Sono d'accordo, l'opzione 4 è generalmente migliore ...

Tuttavia, durante lo sviluppo, lo trovo molto utile per mettere l'intera clausola catch all'interno di un #if (! DEBUG), con un fine all'esterno (per consentire la compilazione in modalità debug):

#if (!DEBUG) 
catch (Exception ex) 
{ 
    // Catch logic for Release mode 
} 
#endif 
finally { } 

Questo rende la rottura API nel punto in cui si è verificato l'errore, anziché al livello superiore.

Basta non abituarsi a #if ...in quasi tutti gli altri casi, utilizzare

[Conditional("DEBUG")] 

di fronte a un metodo, invece

Problemi correlati