Skip to content

[PECOBLR-1655] Implemented the functionality of pool_pre_ping #53

Open
msrathore-db wants to merge 7 commits intomainfrom
PECOBLR-1655
Open

[PECOBLR-1655] Implemented the functionality of pool_pre_ping #53
msrathore-db wants to merge 7 commits intomainfrom
PECOBLR-1655

Conversation

@msrathore-db
Copy link
Collaborator

@msrathore-db msrathore-db commented Jan 21, 2026

Summary

Implements is_disconnect() method to enable connection health checking and prevent "Invalid SessionHandle" errors when connections expire or are closed by the server.

Closes #47

Problem

Users experienced Invalid SessionHandle errors when connections expired or were closed by the server. SQLAlchemy's pool_pre_ping=True feature wasn't working because the dialect didn't
implement is_disconnect() to classify disconnect errors.

When connections died (either before checkout or during query execution), SQLAlchemy couldn't determine if errors were due to disconnects, leaving dead connections in the pool and causing
repeated errors.

Solution

Implements is_disconnect() method that classifies exceptions as disconnect errors, enabling both pessimistic and optimistic disconnect handling as described in SQLAlchemy's pooling documentation.

… to see if the connection is alive. If not it'll recycle the session
@Bidek56
Copy link

Bidek56 commented Jan 21, 2026

@msrathore-db This maybe a better solution.

@msrathore-db msrathore-db changed the title Implemented the functionality of poll_pre_ping Implemented the functionality of pool_pre_ping Jan 21, 2026
@msrathore-db msrathore-db changed the title Implemented the functionality of pool_pre_ping [PECOBLR-1655] Implemented the functionality of pool_pre_ping Feb 5, 2026
Fix CI failures caused by incompatible newer poetry versions by pinning
poetry to version 2.2.1 in all GitHub Actions workflows.

This follows the same fix applied in databricks-sql-python PR #735.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Enhanced is_disconnect() to catch databricks.sql.exc.Error (base class)
and detect "closed connection" errors. This fixes pool_pre_ping failing
when attempting to ping a closed connection.

The default do_ping() tries to create a cursor, which raises Error with
message "Cannot create cursor from closed connection" on closed connections.
Now properly detects this as a disconnect error.

Fixes:
- test_pool_pre_ping_with_closed_connection
- test_is_disconnect_handles_runtime_errors

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@Bidek56
Copy link

Bidek56 commented Feb 9, 2026

@msrathore-db Any ETA on this PR? We are seeing sqlalchemy.exc.DatabaseError: (databricks.sql.exc.DatabaseError) Invalid SessionHandle: SessionHandle which should be resolved by this PR. Thx

@msrathore-db
Copy link
Collaborator Author

@msrathore-db Any ETA on this PR? We are seeing sqlalchemy.exc.DatabaseError: (databricks.sql.exc.DatabaseError) Invalid SessionHandle: SessionHandle which should be resolved by this PR. Thx

We should be able to get it merged and released this week. Thanks

# This catches errors like "Cannot create cursor from closed connection"
if isinstance(e, Error):
error_msg = str(e).lower()
return "closed" in error_msg or "cannot create cursor" in error_msg

Choose a reason for hiding this comment

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

is having closed a definite case for closed connection? There can be error message like cannot be closed etc. Seems to be error prone.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Modified to be precise after checking all error occurences in the python SQL connector. Thanks

from databricks.sql.exc import InterfaceError, DatabaseError, Error

# InterfaceError: Client-side errors (e.g., connection already closed)
if isinstance(e, InterfaceError):

Choose a reason for hiding this comment

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

InterfaceError can also be raised for programming errors like invalid params. Will this be an expected behavior then?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That's not the case with the current connector. All the interface errors are raised when connection is closed.

Copy link

@gopalldb gopalldb left a comment

Choose a reason for hiding this comment

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

LG, minor comments on error handling

- InterfaceError: check for "closed" in message instead of blanket True
- Add RequestError handling for transport/network-level disconnect errors
- Add "unexpectedly closed server side" to DatabaseError disconnect checks
- Keep base Error fallback with precise "closed connection"/"closed cursor"
  matching for older connector versions (v4.0.0-v4.0.5) that raise Error
  instead of InterfaceError
- Expand tests to cover all connector error messages with exact code paths

Co-Authored-By: Claude Opus 4.6 <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.

Invalid SessionHandle: SessionHandle error

3 participants