-
Notifications
You must be signed in to change notification settings - Fork 5.5k
[ci-fix] Use DoNotWrapExceptions across ReflectionMemberAccessor Invoke paths #129212
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
base: main
Are you sure you want to change the base?
Changes from all commits
5281736
9579fbe
c357fbb
b6b94f7
5c1d406
91768ba
8a0b1d0
102e407
6e9eede
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ | |
| using System.Diagnostics; | ||
| using System.Diagnostics.CodeAnalysis; | ||
| using System.Reflection; | ||
| using System.Runtime.ExceptionServices; | ||
|
|
||
| namespace System.Text.Json.Serialization.Metadata | ||
| { | ||
|
|
@@ -33,7 +34,16 @@ public ReflectionMemberAccessor() | |
| : null; | ||
| } | ||
|
|
||
| return () => ctorInfo.Invoke(null); | ||
| return () => | ||
| #if NET | ||
| ctorInfo.Invoke( | ||
| BindingFlags.DoNotWrapExceptions, | ||
| binder: null, | ||
| parameters: null, | ||
| culture: null); | ||
| #else | ||
| ctorInfo.Invoke(null); | ||
| #endif | ||
| } | ||
|
|
||
| public override Func<object[], T> CreateParameterizedConstructor<T>(ConstructorInfo constructor) | ||
|
|
@@ -56,6 +66,13 @@ public override Func<object[], T> CreateParameterizedConstructor<T>(ConstructorI | |
| argsToPass[i] = arguments[i]; | ||
| } | ||
|
|
||
| #if NET | ||
| return (T)constructor.Invoke( | ||
| BindingFlags.DoNotWrapExceptions, | ||
| binder: null, | ||
| parameters: argsToPass, | ||
| culture: null); | ||
| #else | ||
| try | ||
| { | ||
| return (T)constructor.Invoke(argsToPass); | ||
|
|
@@ -67,6 +84,7 @@ public override Func<object[], T> CreateParameterizedConstructor<T>(ConstructorI | |
| // This doesn't apply to the method below as it supports a max of 4 constructor params. | ||
| throw e.InnerException ?? e; | ||
| } | ||
| #endif | ||
| }; | ||
| } | ||
|
|
||
|
|
@@ -108,7 +126,16 @@ public override JsonTypeInfo.ParameterizedConstructorDelegate<T, TArg0, TArg1, T | |
| } | ||
| } | ||
|
|
||
| return (T)constructor.Invoke(arguments); | ||
| return | ||
| #if NET | ||
| (T)constructor.Invoke( | ||
| BindingFlags.DoNotWrapExceptions, | ||
| binder: null, | ||
| parameters: arguments, | ||
| culture: null); | ||
| #else | ||
| (T)constructor.Invoke(arguments); | ||
| #endif | ||
| }; | ||
| } | ||
|
|
||
|
|
@@ -122,6 +149,13 @@ public override JsonTypeInfo.ParameterizedConstructorDelegate<T, TArg0, TArg1, T | |
|
|
||
| return value => | ||
| { | ||
| #if NET | ||
| return (T)constructor.Invoke( | ||
| BindingFlags.DoNotWrapExceptions, | ||
| binder: null, | ||
| parameters: new object?[] { value }, | ||
| culture: null); | ||
| #else | ||
| try | ||
| { | ||
| return (T)constructor.Invoke(new object?[] { value }); | ||
|
|
@@ -130,6 +164,7 @@ public override JsonTypeInfo.ParameterizedConstructorDelegate<T, TArg0, TArg1, T | |
| { | ||
| throw e.InnerException ?? e; | ||
| } | ||
| #endif | ||
| }; | ||
| } | ||
|
|
||
|
|
@@ -143,7 +178,17 @@ public override JsonTypeInfo.ParameterizedConstructorDelegate<T, TArg0, TArg1, T | |
|
|
||
| return delegate (TCollection collection, object? element) | ||
| { | ||
| #if NET | ||
| // Keep exception propagation aligned with ReflectionEmitMemberAccessor. | ||
| addMethod.Invoke( | ||
| collection, | ||
| BindingFlags.DoNotWrapExceptions, | ||
| binder: null, | ||
| parameters: new object[] { element! }, | ||
| culture: null); | ||
| #else | ||
| addMethod.Invoke(collection, new object[] { element! }); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this catch and rethrow the exception like the other cases? |
||
| #endif | ||
| }; | ||
| } | ||
|
|
||
|
|
@@ -167,7 +212,24 @@ public override Func<object, TProperty> CreatePropertyGetter<TProperty>(Property | |
|
|
||
| return delegate (object obj) | ||
| { | ||
| return (TProperty)getMethodInfo.Invoke(obj, null)!; | ||
| #if NET | ||
| return (TProperty)getMethodInfo.Invoke( | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are other
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @copilot resolve this comment
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Addressed in 6e9eede. I audited the other |
||
| obj, | ||
| BindingFlags.DoNotWrapExceptions, | ||
| binder: null, | ||
| parameters: null, | ||
| culture: null)!; | ||
| #else | ||
| try | ||
| { | ||
| return (TProperty)getMethodInfo.Invoke(obj, null)!; | ||
| } | ||
| catch (TargetInvocationException e) when (e.InnerException is not null) | ||
|
jkotas marked this conversation as resolved.
|
||
| { | ||
| ExceptionDispatchInfo.Capture(e.InnerException).Throw(); | ||
| throw; // unreachable | ||
| } | ||
| #endif | ||
| }; | ||
| } | ||
|
|
||
|
|
@@ -177,7 +239,24 @@ public override Func<TDeclaringType, TProperty> CreatePropertyGetter<TDeclaringT | |
|
|
||
| return delegate (TDeclaringType obj) | ||
| { | ||
| return (TProperty)getMethodInfo.Invoke(obj, null)!; | ||
| #if NET | ||
| return (TProperty)getMethodInfo.Invoke( | ||
| obj, | ||
| BindingFlags.DoNotWrapExceptions, | ||
| binder: null, | ||
| parameters: null, | ||
| culture: null)!; | ||
| #else | ||
| try | ||
| { | ||
| return (TProperty)getMethodInfo.Invoke(obj, null)!; | ||
| } | ||
| catch (TargetInvocationException e) when (e.InnerException is not null) | ||
| { | ||
| ExceptionDispatchInfo.Capture(e.InnerException).Throw(); | ||
| throw; // unreachable | ||
| } | ||
| #endif | ||
| }; | ||
| } | ||
|
|
||
|
|
@@ -187,7 +266,23 @@ public override Action<object, TProperty> CreatePropertySetter<TProperty>(Proper | |
|
|
||
| return delegate (object obj, TProperty value) | ||
| { | ||
| setMethodInfo.Invoke(obj, new object[] { value! }); | ||
| #if NET | ||
| setMethodInfo.Invoke( | ||
| obj, | ||
| BindingFlags.DoNotWrapExceptions, | ||
| binder: null, | ||
| parameters: new object[] { value! }, | ||
| culture: null); | ||
| #else | ||
| try | ||
| { | ||
| setMethodInfo.Invoke(obj, new object[] { value! }); | ||
| } | ||
| catch (TargetInvocationException e) when (e.InnerException is not null) | ||
| { | ||
| ExceptionDispatchInfo.Capture(e.InnerException).Throw(); | ||
| } | ||
| #endif | ||
| }; | ||
| } | ||
|
|
||
|
|
@@ -216,10 +311,27 @@ public override UnionTryGetValueAccessor<TUnion> CreateUnionTryGetValueAccessor< | |
| { | ||
| KeyValuePair<Type, MethodInfo> entry = entries[i]; | ||
| caseTypes[i] = entry.Key; | ||
| chain[i] = (UnionTryGetValueAccessor<TUnion>)typeof(ReflectionMemberAccessor) | ||
| object? accessor = typeof(ReflectionMemberAccessor) | ||
| .GetMethod(nameof(CreateUnionTryGetValueAccessorCore), BindingFlags.NonPublic | BindingFlags.Static)! | ||
| .MakeGenericMethod(typeof(TUnion), entry.Key) | ||
| .Invoke(null, new object[] { entry.Value })!; | ||
| #if NET | ||
| .Invoke( | ||
| null, | ||
| BindingFlags.DoNotWrapExceptions, | ||
| binder: null, | ||
| parameters: new object[] { entry.Value }, | ||
| culture: null); | ||
| #else | ||
| .Invoke(null, new object[] { entry.Value }); | ||
| #endif | ||
|
|
||
| if (accessor is null) | ||
| { | ||
| throw new InvalidOperationException( | ||
| $"Failed to create union accessor for type '{entry.Key}' using method '{entry.Value}'."); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This unrelated change. It should be left for separate PR (and tests should be added to cover it in that PR) |
||
| } | ||
|
|
||
| chain[i] = (UnionTryGetValueAccessor<TUnion>)accessor; | ||
| } | ||
|
|
||
| return (TUnion union, out Type? caseType, out object? value) => | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the pattern for catch and rethrow be consistent across all cases?