Skip to content

Fix LoginWithFailover missing parser state check#4140

Open
paulmedynski wants to merge 1 commit intomainfrom
dev/paul/4139-failover-parser-state-check
Open

Fix LoginWithFailover missing parser state check#4140
paulmedynski wants to merge 1 commit intomainfrom
dev/paul/4139-failover-parser-state-check

Conversation

@paulmedynski
Copy link
Copy Markdown
Contributor

Fixes #4139

Description

LoginWithFailover() in SqlConnectionInternal.cs was missing the _parser?.State check that LoginNoFailover() already has. This caused transient errors (40613, 42108, 42109) to trigger failover alternation instead of being thrown immediately for the outer ConnectRetryCount loop to handle.

The code comment in LoginWithFailover() even notes: "The logic in this method is paralleled by the logic in LoginNoFailover. Changes to either one should be examined to see if they need to be reflected in the other."

Changes

Added the same _parser?.State is not TdsParserState.Closed check to LoginWithFailover() catch block, consistent with LoginNoFailover():

  • Login-phase errors (transient errors, explicit server rejections where parser is still open): throw immediately, handled by outer retry loop
  • Network errors (parser is closed): continue failover alternation as before

Testing

  • All 21 ConnectionFailoverTests pass on net8.0 and net9.0
  • TransientFault_WithUserProvidedPartner_RetryDisabled_ShouldFail now correctly fails with the expected SqlException
  • Network error failover tests continue to work (parser is closed in those cases)
  • No regressions in full unit test suite

LoginWithFailover() was missing the _parser?.State check that
LoginNoFailover() already has. This caused transient errors (40613,
42108, 42109) to trigger failover alternation instead of being thrown
immediately for the outer ConnectRetryCount loop to handle.

Added the same parser state check so that login-phase errors (parser
open) throw immediately while network errors (parser closed) continue
failover alternation.

Fixes #4139
@paulmedynski paulmedynski added this to the 7.1.0-preview1 milestone Apr 6, 2026
@paulmedynski paulmedynski requested a review from a team as a code owner April 6, 2026 13:09
@github-project-automation github-project-automation bot moved this to To triage in SqlClient Board Apr 6, 2026
Copilot AI review requested due to automatic review settings April 6, 2026 13:09
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a failover login behavior discrepancy in SqlConnectionInternal.LoginWithFailover() by aligning its error-handling logic with LoginNoFailover(), ensuring login-phase transient/server errors are thrown for the outer ConnectRetryCount retry loop instead of triggering failover alternation.

Changes:

  • Added a _parser?.State is not TdsParserState.Closed check in LoginWithFailover()’s SqlException catch block.
  • Documented the rationale in-code to distinguish login-phase errors from network-level failures during failover alternation.

Comment on lines +3665 to +3669
// If state != closed, indicates that the parser encountered an error while
// processing the login response (e.g. an explicit error token). Transient
// network errors that impact connectivity will result in parser state being
// closed. Only network-level errors should trigger failover alternation;
// login-phase errors (like transient errors) should be thrown so they can
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

Minor grammar/clarity: the new comment reads "If state != closed, indicates...". Consider rephrasing to "If state != Closed, it indicates..." (and optionally reference TdsParserState.Closed explicitly) to match the code and improve readability.

Copilot uses AI. Check for mistakes.
@paulmedynski paulmedynski moved this from To triage to In review in SqlClient Board Apr 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

LoginWithFailover missing parser state check causes transient errors to trigger failover instead of retry

2 participants