Skip to content

Throw NpgsqlException instead of InvalidOperationException on a broken connection#6599

Draft
irrationalmentality wants to merge 1 commit into
npgsql:mainfrom
irrationalmentality:fix/5605-broken-connection-npgsqlexception
Draft

Throw NpgsqlException instead of InvalidOperationException on a broken connection#6599
irrationalmentality wants to merge 1 commit into
npgsql:mainfrom
irrationalmentality:fix/5605-broken-connection-npgsqlexception

Conversation

@irrationalmentality
Copy link
Copy Markdown

Fixes #5605.

Problem

When a connection is broken (e.g. by a keepalive failure), CheckReady / CheckOpen treated the Broken state the same as Closed and threw InvalidOperationException("Connection is not open"). Connection errors are supposed to surface as NpgsqlException, so callers can catch them at a higher level, dispose their DB resources and reconnect — InvalidOperationException can't reasonably be handled that way.

Change

  • Split the Broken case from Closed in both CheckReady and CheckOpen. Broken now throws NpgsqlException; Closed (never opened / closed after normal use) keeps throwing InvalidOperationException("Connection is not open").
  • The message points to the logs: as @NinoFloris noted on the issue, the original break reason isn't reachable from the connection (the connector is detached on break), but it is logged when the connector breaks.
  • Removed a stale doc note on ConnectorState.Broken ("This state isn't implemented yet").

Re: the two questions in my issue comment — the original exception can't be attached as InnerException at the connection level without extra plumbing (glad to add that as a follow-up if you'd like), and both CheckReady and CheckOpen are covered.

Behavioral change

This changes the exception type for operations on a broken connection from InvalidOperationException to NpgsqlException (NpgsqlException : DbException, so catch (DbException) now catches it while catch (InvalidOperationException) no longer does). Flagging in case it warrants the breaking change label / a release-notes entry — it targets 11.0.

Tests

Added Broken_connection_throws_NpgsqlException_not_InvalidOperationException in ConnectionTests. Ran it plus the full ConnectionTests and transaction test classes against a local PG 17: 224 passed, 0 failed (only the expected platform skips).

🤖 Generated with Claude Code

…connection

When a connection was broken (e.g. by a keepalive failure), CheckReady/CheckOpen treated the Broken state identically to Closed and threw InvalidOperationException ("Connection is not open"). Connection errors should surface as NpgsqlException so callers can handle them as connection failures and recover.

Split the Broken case from Closed in both checks and throw NpgsqlException with a message pointing to the logs. The original break reason is logged when the connector breaks but is not reachable from the connection (which is detached on break), matching the maintainer guidance on npgsql#5605.

Also remove the stale doc note claiming ConnectorState.Broken is not implemented yet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

InvalidOperationException instead of NpgsqlException when client disconnects

1 participant