I want to throw an exception but with custom message and persist stacktrace too. I've gone through various threads.
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 last appraoch is used (with custom exception constructor calling base class constructor), output on screen of death is something like:
**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
Good thing is everything is there on screen. But, on top I want my exception to display i.e. "new message" and not original message.
Hence reconciling my question: HOW can I display on screen of death the original stack trace but with a custom error Message?
Rule description To keep the original stack trace information with the exception, use the throw statement without specifying the exception.
When the exception is restored, the following string is inserted in the stack trace to indicate the restore point: "End of stack trace from the previous location where the exception was thrown". This is similar to the way inner exceptions or marshaled exceptions are indicated in stack traces.
Yes. If you create a new Exception() and don't throw it, every property except Data and Message will be null.
Therefore, you should log a stacktrace if, and only if, and always if, the exception indicates a bug in the program. However, that does not always indicate that a method you write should catch and log the exception.
throw new CustomException("My message",ex);// same as above (... stacktrace lost)
Your conclusion in the comments is wrong on the last one. The stacktrace is kept in the inner Exception. Standard reporting (including Exception.ToString()
) will report the full stacktrace. This is what you are seeing when you get the constructor right. (Always call the correct base ctor!).
But I don't recognize [WebException]
. In WCF you need
<serviceDebug includeExceptionDetailInFaults="true"/>
I guess your Web environment has a similar feature of suppressing error info towards the client.
Using your fourth approach is how it is generally done and the established pattern. You shouldn't confuse exception handling (or raising) with the way how they are displayed or logged, or whatever.
If you have the output of the (caught) exception under control, i.e. can change/write the respective code, you could simply use the Exception.ToString()
method, which would print the outer exception, including all "inner" ones.
Remark:
Sometimes the inner exceptions are not displayed on purpose by an application. For example in WCF (Windows Communication Foundation) the inner exception is not even transferred from the server to the client unless IncludeExceptionDetails
(via config, code, ...) is set. This usually is done because the inner exception is considered an implementation detail, which may provide an attacker with valuable information to break your application.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With