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
Add a way to opt out of TargetInvocationException wrapping on late-bound invokes. #23023
Comments
@MichalStrehovsky - Thoughts? This does seem like a pragmatic way to address a behavior that's been a long-standing irritance (at least for me.) |
Heh, I never even saw the overload of Invoke/GetValue/SetValue that takes Do we want to also take this opportunity to propose an overload of |
|
Surely |
Making it also work for private constructors is a bunch of work for AOT, so I would propose we make |
True, it could be worth losing the syntactic sugar of
Could it slow-path through |
It could, but it always makes me sad to have APIs with perf characteristics that can't be reasoned about (sure, we could document that, but who reads docs?). If we make |
To the consumer, the main speed difference between slow and not working is how quickly they get sad. |
There are also other ways to achieve non-exception-wrapping In any case, we should probably keep that separate from this api proposal. If the basic notion of a non-wrapping Invoke doesn't fly with the api review folks, figuring out how to extend it to the generic CreateInstance becomes moot. |
Cleaned up the proposal a bit and promoted to api-ready-for-review. We can tackle the |
Looks good, the only suggestion is to rename var bf = BindingFlags.Public | BindingFlags.DoNotWrapExceptions; |
That has nice didactic qualities too: Seeing |
Next steps: will add the enum value to |
Marking as up-for-grabs. |
FYI: The API review discussion was recorded - see https://youtu.be/VppFZYG-9cA?t=5527 (duration: 14 min) |
This was approved here. https://github.com/dotnet/corefx/issues/22866 This does not implement the feature, it just adds the member to the enum so that CoreCLR and CoreRT will agree on the value.
This was approved here. https://github.com/dotnet/corefx/issues/22866 Ok, this one actually makes the feature work. Turned out not to be too hard. There are a couple of drive-by items being done here: - Since the other Invoke overload on MethodInvoker was only for its use, downgraded its visibility. - Moved the catch in InvokeUtilites before the finally that copies back arguments. We don't want to wrap any exceptions out of the argument post-processing steps.
Project N implementation is now merged. CoreCLR implementation is still up for grabs. The exception wrapping seems to occur in various places in C++ code so this will require some C++ work. |
…13767) * Support for not wrapping exceptions with TargetInvocationException. For dotnet/corefx#22866. * Respond to PR feedback. Mainly by making "WrapExceptions" consistently positive in FCalls. * Remove BindingFlags.DoNotWrapExceptions tests in deference to CoreFX tests.
The original design review is here: dotnet/corefx#22866 . To summarize, this adds a new flag to `BindingFlags` called `DoNotWrapExceptions`. When this flag is used to invoke a method using reflection, any exceptions thrown are not wrapped with a `TargetInvocationException`. It has already been implemented in some other version of .NET: - dotnet/corert#4437 - dotnet/coreclr#13767 I would be delighted if this handy feature was also available in Mono. I have in part based my changes on the CoreCLR implementation. There all already tests for this feature in corefx, so I have added those to the corlib_xtest.dll.sources file. I have a couple of concerns about my implementation: - I notice that `DynamicMethod.Invoke` was ignoring the BindingFlags and other arguments. I changed this method to pass along all the arguments. For what it's worth, it appears that [CoreCLR respects](https://github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/Reflection/Emit/DynamicMethod.cs#L488) these arguments.
Late-bound invokes through Reflection wrap exceptions thrown by the target in a
TargetInvocationException
. In many cases, this behavior is not desired and counter-productive. For those who want the actual exception, it requires unwrapping theTargetInvocationException
to rethrow the inner exception and to retrieve the full call stack. The fact that every exception is "caught" hampers the normal debugging experience. It'd be useful to have a way to opt out of this wrapping.We can do this without adding lots of new overloads by adding a new member to the
BindingFlags
enum:BindingFlag.DoNotWrapExceptions
. Setting this bit would disable the wrapping behavior.Here is a fiddle of the code sample included below: https://dotnetfiddle.net/o9qUht
Apis that would be affected:
[EDIT] Added C# syntax highlight by @karelz
The text was updated successfully, but these errors were encountered: