Skip to content

Repro Test for #3720 (Unobserved Exception)#4460

Open
benrr101 wants to merge 6 commits into
mainfrom
dev/russellben/3720-unobserved
Open

Repro Test for #3720 (Unobserved Exception)#4460
benrr101 wants to merge 6 commits into
mainfrom
dev/russellben/3720-unobserved

Conversation

@benrr101

Copy link
Copy Markdown
Contributor

Description

This PR provides a reliable reproduction of #3720 in which an exception produced by the AsyncIOCompletionCallback of the SNI Packet class is not observed, leading to the unobserved exception handler being invoked.

This PR does not attempt to fix the issue, just adds a test that can be used to verify that the behavior exists. Attempts to fix the issue will inherently break this test, but can easily be fixed by changing the single assert in the test from "IsNotNull" to "IsNull".

Issues

#3720

Testing

Ran for hundreds of iterations with no failures observed.

@benrr101 benrr101 added this to the 7.1.0-preview3 milestone Jul 20, 2026
@benrr101
benrr101 requested a review from a team as a code owner July 20, 2026 23:05
@benrr101 benrr101 added the Area\Tests Issues that are targeted to tests or test projects label Jul 20, 2026
Copilot AI review requested due to automatic review settings July 20, 2026 23:05
@github-project-automation github-project-automation Bot moved this to To triage in SqlClient Board Jul 20, 2026

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

Adds unit-test infrastructure and a targeted repro test for issue #3720, demonstrating that exceptions thrown from SniPacket’s async IO completion callback can go unobserved and later surface via TaskScheduler.UnobservedTaskException.

Changes:

  • Introduces a shared ObservableException test utility to uniquely tag unobserved exceptions.
  • Refactors AsyncHelperTest to use the shared ObservableException instead of an inline nested type.
  • Adds a new Managed SNI unit test that reliably reproduces the unobserved-exception behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
src/Microsoft.Data.SqlClient/tests/UnitTests/Utilities/ObservableException.cs Adds a reusable exception type for unobserved-exception testing scenarios.
src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/Utilities/AsyncHelperTest.cs Removes the inline ObservableException in favor of the shared utility type.
src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ManagedSni/SniPacketAsyncCallbackTest.cs Adds a repro test for unobserved exceptions originating from SniPacket async callbacks.

Comment thread src/Microsoft.Data.SqlClient/tests/UnitTests/Utilities/ObservableException.cs Outdated
Comment thread src/Microsoft.Data.SqlClient/tests/UnitTests/Utilities/ObservableException.cs Outdated
@paulmedynski paulmedynski moved this from To triage to In review in SqlClient Board Jul 21, 2026

@paulmedynski paulmedynski 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.

Blocking on Copilot feedback. My suggestion about ObservableException is at your discretion.

/// Represents a utility exception designed for testing scenarios where exceptions must be observed.
/// </summary>
/// <param name="id">Identifier to uniquely identify the </param>
public ObservableException(Guid id)

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.

Should this class generate its own GUID? Not sure it needs one injected, or that it needs a setter:

public class ObservableException : Exception
{
  public Guid Identifier { get; } = new();
}

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.

I guess there is one existing use of this class, but it could be esaily re-arranged to work with the above.

I generally try to avoid providing any unnecessary API surface.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I have a bit of a grander idea for it ... so I might omit this change for now 😬

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ok, scope creep time, I turned the structure of the observable exception testing into a disposable helper that takes care of its own setup and cleanup. This also consolidates the flakiness hardening into one spot. The async helper tests have been updated to use this (and as a result the tests take longer, but it is robust to flakiness - within reason).

@github-project-automation github-project-automation Bot moved this from In review to Waiting for customer in SqlClient Board Jul 21, 2026
Copilot AI review requested due to automatic review settings July 21, 2026 20:50

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 3 out of 3 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ManagedSni/SniPacketTests.cs:47

  • The unobserved-exception filter is currently using InnerExceptions.Contains(testException), which relies on reference equality. This makes the test more brittle and also diverges from the ObservableException remarks and existing AsyncHelperTest pattern (match by Identifier). Consider matching ObservableException.Identifier instead (without LINQ, per prior discussion).
            EventHandler<UnobservedTaskExceptionEventArgs> handleUnobservedException =
                (_, args) =>
                {
                    if (args.Exception.InnerExceptions.Contains(testException))
                    {
                        args.SetObserved();
                        unobservedExceptionRaised.TrySetResult(args.Exception);
                    }
                };

Comment thread src/Microsoft.Data.SqlClient/tests/UnitTests/Utilities/ObservableException.cs Outdated
@codecov

codecov Bot commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 64.87%. Comparing base (fdebcd2) to head (f39f395).
⚠️ Report is 23 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4460      +/-   ##
==========================================
- Coverage   65.83%   64.87%   -0.96%     
==========================================
  Files         287      287              
  Lines       43763    66958   +23195     
==========================================
+ Hits        28812    43440   +14628     
- Misses      14951    23518    +8567     
Flag Coverage Δ
CI-SqlClient ?
PR-SqlClient-Project 64.87% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI review requested due to automatic review settings July 22, 2026 19:04

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 3 out of 3 changed files in this pull request and generated 3 comments.

Copilot AI review requested due to automatic review settings July 22, 2026 23:07

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 3 out of 3 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area\Tests Issues that are targeted to tests or test projects

Projects

Status: Waiting for customer

Development

Successfully merging this pull request may close these issues.

4 participants