Skip to content

[ci-fix] Use DoNotWrapExceptions across ReflectionMemberAccessor Invoke paths#129212

Open
github-actions[bot] wants to merge 10 commits into
mainfrom
ci-fix/reflection-unwrap-tie-128766-da9341c6f0fcce74
Open

[ci-fix] Use DoNotWrapExceptions across ReflectionMemberAccessor Invoke paths#129212
github-actions[bot] wants to merge 10 commits into
mainfrom
ci-fix/reflection-unwrap-tie-128766-da9341c6f0fcce74

Conversation

@github-actions

@github-actions github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Workflow artifact: ci-fix
Artifact kind: help
Linked KBE: #128766

> [!NOTE]
> This is an AI/Copilot-generated fix updated after PR feedback and validated with targeted local build/test runs.

Root cause (best analysis)

AsyncEnumerableTests.SerializeAsyncEnumerable_*_PartialItemFailure_PriorItemsAreFullyWritten fails on tvos-arm64 AllSubsets_Mono because the test expects InvalidOperationException but receives TargetInvocationException.

The failing log line:

[FAIL] ...AsyncEnumerableTests_AsyncPipeSerializer.SerializeAsyncEnumerable_TopLevelValues_PartialItemFailure_PriorItemsAreFullyWritten
Expected: typeof(System.InvalidOperationException)
Actual:   typeof(System.Reflection.TargetInvocationException)

On Mono/tvOS (AOT environments), System.Text.Json uses ReflectionMemberAccessor, where reflection Invoke can wrap target exceptions. CoreCLR commonly uses ReflectionEmitMemberAccessor, which propagates underlying exceptions directly.

Attempted fix

Updated ReflectionMemberAccessor to apply BindingFlags.DoNotWrapExceptions on NET targets across relevant reflection Invoke call sites in the file (including property accessors and other Invoke usages raised in review), while preserving non-NET compatibility paths.

Additional polish from feedback:

  • Kept exception behavior aligned with ReflectionEmitMemberAccessor for add-method delegate behavior.
  • Improved null-handling/diagnostics for union accessor delegate creation.

What is unverified / where I need help

  • Full matrix/platform validation (especially tvOS Mono) still depends on CI legs; local validation was targeted.

Validation

  • ./build.sh clr+libs -rc release
  • ./build.sh clr+libs+host -rc release -lc release
  • dotnet build src/libraries/System.Text.Json/src/System.Text.Json.csproj -c Release
  • dotnet build /t:test src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj -p:Configuration=Release /p:XunitMethodName=System.Text.Json.Serialization.Tests.AsyncEnumerableTests_AsyncPipeSerializer.SerializeAsyncEnumerable_TopLevelValues_PartialItemFailure_PriorItemsAreFullyWritten

Evidence

Help wanted

  • Area owners (area-System.Text.Json): @StephenMolloy, @dotnet/area-system-text-json

Filed by ci-failure-fix. Comment here or on the workflow file to suggest changes; ci-failure-scan-feedback reads in-scope feedback daily and opens (or updates) a PR with prompt edits.

> [!WARNING]
>

> Generated by CI Outer-Loop Failure Fixer · ● 35M ·

… accessors

On Mono/tvOS (AOT environments), System.Text.Json uses ReflectionMemberAccessor
which calls MethodInfo.Invoke() for property getters/setters. This wraps any
exception thrown by the property in TargetInvocationException, unlike CoreCLR
which uses IL-emitted delegates that propagate exceptions directly.

The constructor delegates in the same class already unwrap
TargetInvocationException; this commit adds the same treatment to
CreatePropertyGetter and CreatePropertySetter using
ExceptionDispatchInfo.Capture to preserve the original stack trace.

Fixes the tvOS Mono test failure where
AsyncEnumerableTests.SerializeAsyncEnumerable_PartialItemFailure tests
expect InvalidOperationException but receive TargetInvocationException.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@kotlarmilos kotlarmilos changed the title [ci-fix] Needs review: Unwrap TargetInvocationException in ReflectionMemberAccessor property accessors (refs #128766) [ci-fix] Unwrap TargetInvocationException in ReflectionMemberAccessor property accessors Jun 10, 2026
Co-authored-by: kotlarmilos <11523312+kotlarmilos@users.noreply.github.com>
Copilot AI requested a review from kotlarmilos June 16, 2026 10:49
Copilot AI and others added 6 commits June 17, 2026 07:11
Co-authored-by: kotlarmilos <11523312+kotlarmilos@users.noreply.github.com>
Co-authored-by: kotlarmilos <11523312+kotlarmilos@users.noreply.github.com>
Co-authored-by: kotlarmilos <11523312+kotlarmilos@users.noreply.github.com>
Co-authored-by: kotlarmilos <11523312+kotlarmilos@users.noreply.github.com>
Co-authored-by: kotlarmilos <11523312+kotlarmilos@users.noreply.github.com>
Co-authored-by: kotlarmilos <11523312+kotlarmilos@users.noreply.github.com>
Copilot AI changed the title [ci-fix] Unwrap TargetInvocationException in ReflectionMemberAccessor property accessors [ci-fix] Use DoNotWrapExceptions across ReflectionMemberAccessor Invoke paths Jun 17, 2026
@github-actions github-actions Bot mentioned this pull request Jun 18, 2026
…essor Invoke paths

Apply BindingFlags.DoNotWrapExceptions on NET and a single stack preserving ExceptionDispatchInfo based catch and rethrow on non NET across every user code Invoke site, and revert the unrelated union accessor null check for a separate PR.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@kotlarmilos kotlarmilos marked this pull request as ready for review July 3, 2026 11:05
Copilot AI review requested due to automatic review settings July 3, 2026 11:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates System.Text.Json’s reflection-based MemberAccessor implementation to avoid TargetInvocationException wrapping when invoking constructors/methods via reflection, aligning exception propagation with the ReflectionEmit-based accessor paths.

Changes:

  • Use BindingFlags.DoNotWrapExceptions for reflection Invoke calls when targeting #if NET.
  • On non-NET TFMs, unwrap TargetInvocationException.InnerException via ExceptionDispatchInfo to preserve the original exception and stack.
  • Apply this across parameterless/parameterized constructors, add-method delegates, and property getter/setter delegates.
Show a summary per file
File Description
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionMemberAccessor.cs Adjusts reflection invocation patterns to avoid exception wrapping and preserve original exception behavior.

Copilot's findings

  • Files reviewed: 1/1 changed files
  • Comments generated: 1

Comment on lines +37 to +45
return () =>
{
#if NET
return ctorInfo.Invoke(
BindingFlags.DoNotWrapExceptions,
binder: null,
parameters: null,
culture: null);
#else
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants