Skip to content

Add runtime async tests for catching non-Exception throws#130506

Merged
VSadov merged 8 commits into
mainfrom
copilot/runtime-async-tests-for-non-exceptions
Jul 23, 2026
Merged

Add runtime async tests for catching non-Exception throws#130506
VSadov merged 8 commits into
mainfrom
copilot/runtime-async-tests-for-non-exceptions

Conversation

Copilot AI commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Runtime async (async2) is meant to match compiler state-machine async (async1). No coverage existed for catching objects that don't derive from System.Exception (only throwable via IL), where RuntimeCompatibilityAttribute(WrapNonExceptionThrows) governs whether the object surfaces as a RuntimeWrappedException. These tests close that hole and pin down where the two forms agree and diverge.

Description

New tests under src/tests/async/runtime-wrapped-exception/:

  • NonExceptionThrower.il — IL helper that throws a non-Exception object (a string), since C# can't express this.
  • NoWrapThrowers.cs — helper assembly marked [assembly: RuntimeCompatibility(WrapNonExceptionThrows = false)] with async1/async2 throwers. The attribute is assembly-scoped, so an opt-out variant requires its own assembly.
  • runtime-wrapped-exception.cs — awaits each thrower (async1 via [RuntimeAsyncMethodGeneration(false)], async2 by default) and asserts the caller observes a RuntimeWrappedException wrapping the thrown object, for throws both before and after a suspension point, under both WrapNonExceptionThrows settings.

Observed behavior:

  • WrapNonExceptionThrows = true (C#/CoreLib default): async1 and async2 match — caller sees RuntimeWrappedException in all cases.
  • WrapNonExceptionThrows = false: they match for a synchronous (pre-yield) throw and for async2 after a yield. They diverge for a non-Exception thrown after a suspension point — async2 faults the Task with a RuntimeWrappedException, while async1 lets the raw object escape onto the thread pool and crash the process.

The divergent (crashing) case, CatchAfterYield_NoWrap_Async1, is disabled with [ActiveIssue("https://github.com/dotnet/runtime/issues/123194")], which unconditionally skips it and keeps it out of the merged runner so it can't abort the process. The remaining 7 tests run.

// async1 (state machine) vs async2 (runtime async) — same body, different generation
public static async Task ThrowAfterYieldAsync2()
{
    await Task.Yield();
    NonExceptionThrower.ThrowNonException(); // throws a string (IL)
}

[RuntimeAsyncMethodGeneration(false)]
public static async Task ThrowAfterYieldAsync1()
{
    await Task.Yield();
    NonExceptionThrower.ThrowNonException();
}

Copilot AI requested review from Copilot and removed request for Copilot July 10, 2026 17:27
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @agocke
See info in area-owners.md if you want to be subscribed.

Copilot AI linked an issue Jul 10, 2026 that may be closed by this pull request
Copilot AI requested review from Copilot and removed request for Copilot July 10, 2026 18:03
Copilot AI changed the title [WIP] Add tests for runtime async non-exception behaviors Add runtime async tests for catching non-Exception throws Jul 10, 2026
Copilot AI requested a review from VSadov July 10, 2026 18:15
Copilot AI temporarily deployed to copilot-pat-pool July 10, 2026 21:47 Inactive
Copilot AI temporarily deployed to copilot-pat-pool July 10, 2026 21:47 Inactive
Co-authored-by: VSadov <8218165+VSadov@users.noreply.github.com>

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

Copilot reviewed 6 out of 7 changed files in this pull request and generated 1 comment.

Add Condition="'$(Language)' == 'C#'" to the RuntimeAsyncMethodGenerationAttribute.cs
Compile Include in src/tests/async/Directory.Build.props so it is not injected
into .ilproj projects. Remove the now-unnecessary <Compile Remove> workarounds
from async-versions.ilproj and NonExceptionThrower.ilproj.

Co-authored-by: VSadov <8218165+VSadov@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 21, 2026 19:43

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.

Copilot was unable to review this pull request because there is no eligible user to bill. To allow Copilot reviews on bot-authored pull requests, enable direct organization billing in your organization's Copilot settings.

@VSadov

VSadov commented Jul 21, 2026

Copy link
Copy Markdown
Member

@copilot per suggestion from @MichalStrehovsky, please use #69919 for blocking the test on NativeAOT. (the issue already covers general scenarios with non-Exception throws on NativeAOT)

Co-authored-by: VSadov <8218165+VSadov@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 21, 2026 20:56

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.

Copilot was unable to review this pull request because there is no eligible user to bill. To allow Copilot reviews on bot-authored pull requests, enable direct organization billing in your organization's Copilot settings.

Copilot AI commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

@copilot per suggestion from @MichalStrehovsky, please use #69919 for blocking the test on NativeAOT. (the issue already covers general scenarios with non-Exce...

Updated in the latest commit — the NativeAOT blocking comment now references #69919.

@VSadov

VSadov commented Jul 22, 2026

Copy link
Copy Markdown
Member

@copilot there is ‎reflect_ai.csx in the changes with only whitespace changes. I think that should be reverted.

Co-authored-by: VSadov <8218165+VSadov@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 22, 2026 15:47

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.

Copilot was unable to review this pull request because there is no eligible user to bill. To allow Copilot reviews on bot-authored pull requests, enable direct organization billing in your organization's Copilot settings.

Copilot AI commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

@copilot there is ‎reflect_ai.csx in the changes with only whitespace changes. I think that should be reverted.

Removed in the latest commit.

@VSadov
VSadov marked this pull request as ready for review July 22, 2026 22:33
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
13 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@VSadov
VSadov requested a review from MichalStrehovsky July 22, 2026 22:36
@VSadov
VSadov merged commit e4f7353 into main Jul 23, 2026
84 checks passed
@VSadov
VSadov deleted the copilot/runtime-async-tests-for-non-exceptions branch July 23, 2026 06:40
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.

Runtime async needs tests for catching non-exceptions which are thrown

6 participants