-
Notifications
You must be signed in to change notification settings - Fork 4.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow setting the stack trace on deserialized exception object #17571
Comments
This issue is broken out from #17144, see context there. CC all people who commented on the original issue #17144 Having Exception.StackTrace setter was requested before we had the serialization constructors exposed on the Exception class. now we have the serialization constructors which can be used to deserialize the exception object. StackTrace setter is not really needed now except if we need to enable serialization scenarios which not using the serialization constructors. I can see exposing it will be useful for such serialization scenario but it will be interesting for non-serialization scenario to allow having a setter for exception stack trace. and it is not clear either if we need to support such serialization scenarios, the Exception class will not be only type will have such issue but I expect many other types will have similar issue. what all think about that? do you still think we need to expose this property? |
Removing the label since as you say this is no longer required for our NS2.0 goal. It seems to me this is a feature at this point and not something that needs doing right now. |
My opinion has always been that making the stacktrace settable is not a
|
I'm happy that the constructors are back. ISerializable is not the best
|
Thanks @eiriktsarpalis. |
I have seen people set a custom stack trace... I agree it should be gone, it will break some people tho. |
@tarekgh The current plan is not support binary serialization accross different versions of the runtime/framework. The solution based on binary serialization assumes that there is same version of the runtime/framework running on all machines. I do not think it is safe to make this assumption. |
CC @weshaggard |
@tarekgh Is this something we have decided to take? |
@joperezr Yes I am going to work on the proposal next week and then will mark it as ready for review. |
@jkotas I have added the proposal on the top of this issue, could you please have a look and send your feedback? I already marked the issue ready for design review. |
Have you considered exposing it on ExceptionDispatchInfo as a design alternative? It would make the setter to be less in your face. @gkhanna79 Any comments about this API proposal? |
@jkotas Agree 100% with moving this to ExceptionDispatchInfo. Modifying stacktraces should only be made available to library/framework authors, and thus hidden from common view. |
Agree also on that. |
@jkotas it looks having it on ExceptionDispatchInfo could be better choice. thanks for pointing to that. |
I concur - ExceptionDispatchInfo is way more appropriate for this task and does have the notion of "propagating" stacktraces that can be leveraged to address this scenario. |
I have updated the proposal according to the feedback. thanks all for your feedback. |
I think not exposing a setter for the stack trace on
will not preseve the original stack trace but will append the new stack trace to preserve diagnostic information. |
@terrajobst in the current proposal in the behavior section, I proposed to overwrite the stack trace and not to append it. The reason is we are addressing the serialization scenario which doesn't need the append here. also with the current proposal, people still can append their stack if they need to just by getting the stack trace then append whatever they like and then set it back. |
Set also sounds more logical than append IMO |
@danmosemsft do you believe this is still necessary? |
I don't see the need given we have serialization. Maybe close and see whether we get feedback. |
I am using a grpc interceptor to catch all exceptions thrown on the server side, serialise them, intercept on the client side, catch the exception and rethrow it. The problem with this approach is that either I only get the stack trace on the server end, or I only get the stack trace on the client end. Neither is sufficient to diagnose why the exception was thrown. I need a way to merge the stack traces, and this proposal looks like it would provide such a capability. |
@YairHalberstadt can you wrap the exception on the client side and rethrow that? |
@danmosemsft That's what I'm doing, but a key purpose of serialising the exception is to be able to differentiate in catch clauses on the type of exception. Now we have to catch our wrapper exception and switch on the inner exception type. Certainly not the worst thing in the world, but I think this presents a valid use case for this API. |
I think using inner exception would be reasonable here, at least you'll have 2 exception objects instead of merging stack trace. The other similar idea is to use AggregateException and wrap all exceptions inside one object? |
Is this being considered? Throwing an AggregateException will violate the promise of await as await should not throw AggrgateException. So throwing my new exception which has the the actual server info as inner exception is the only option. |
Proposal
Provide a setter property for SourceExceptionStackTrace in ExceptionDispatchInfo class
Details
Exception serialization scenario is challenging as there is no easy way can deserialize an exception object and include the stack trace in the de-serialized object. The reason is Exception lack supporting a StackTrace setter property or providing a constructor that can take stack trace as a paramter. The net core supports binary serialization which can serialize and de-serialize the exception objects including the stack trace but this approach is not helping much for the following reasons:
To support the scenario, we need to add SourceExceptionStackTrace property to ExceptionDispatchInfo class. The following code demonstrate how ExceptionDispatchInfo can be used to get the exception with the original serialized stack trace and also how to throw the exception with the new stack trace.
Behavior ExceptionDispatchInfo.SourceExceptionStackTrace
The setter of this property will overwrite the current source trace on the source exception. the setter will not affect any other properties in the source exception object.
The getter will return the stack trace from the source exception. this can be empty string if there is no stack trace in the source #exception
Alternative Design
We can think in adding a setter for Exception.StackTrace property or expose a method like Exception AddPreservedStack(string stackTrace))
I got some feedback from different people that they don't like this option as in the main scenarios nobody should set the stack trace on the exception objects and this option can cause confusion and people misuse it.
The text was updated successfully, but these errors were encountered: