Throw an exception but keep the stack trace

I want to throw an exception, but with a custom message and save the stack. I went through various streams.

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 } 

When the last evaluation code is used (with the base class constructor constructor creating the special exception constructor), the output to the death screen looks something like this:

 **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 

It's good that everything is on the screen. But, at the top, I want my exception to be displayed, that is, a "new message" and not the original message.

So, reconciling my question: HOW can I display the original stack trace on the death screen, but with a custom error message?

+6
source share
4 answers
  throw new CustomException("My message",ex);// same as above (... stacktrace lost) 

Your conclusion in the comments is incorrect at the last. The stacktrace element is stored in an internal Exception. Standard reporting (including Exception.ToString() ) will report the full stack. This is what you see when you build the constructor correctly. (Always call the correct base ctor!).

But I do not recognize [WebException] . In WCF you need

  <serviceDebug includeExceptionDetailInFaults="true"/> 

I assume that your web environment has a similar function to suppress error information in relation to the client.

+8
source

Using your fourth approach is how it is done in general and an established template. You should not confuse exception handling (or raising) with how they are displayed or logged, or anything else.

If you have the result of a (caught) exception under control, i.e. can change / write the corresponding code, you can just use the Exception.ToString() method, which will print the external exception, including all the "internal" ones.

Note: Sometimes internal exceptions are not displayed by the target application. For example, in WCF (Windows Communication Foundation), an internal exception is not even transferred from the server to the client unless IncludeExceptionDetails set (via config, code, ...). This is usually done because an internal exception is considered an implementation detail that can provide the attacker with valuable information to break your application.

+3
source

How about overriding the StackTrace property?

 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
source

I agree, option 4 is usually the best ...

HOWEVER, during development, it is very useful for me to put the entire catch clause inside #if (! DEBUG), and finally outside it (to allow compilation in debug mode):

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

This causes the API to break at the point where the error occurred, and not at the top level.

Just don't make #if habits ... in almost all other cases, use

 [Conditional("DEBUG")] 

before the method instead

0
source

Source: https://habr.com/ru/post/896704/


All Articles