diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-05-30 12:29:58 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-05-31 15:06:28 -0400 |
commit | ad14471bc99c2fb2315d3333a95dd3d7bf0a33a7 (patch) | |
tree | 8eb1feafcd1fcc73437363ca22be536a6de79f77 /lib/sqlalchemy/engine/base.py | |
parent | d97de97eff21af3bdacffc2b625feb7e0bd6c18c (diff) | |
download | sqlalchemy-ad14471bc99c2fb2315d3333a95dd3d7bf0a33a7.tar.gz |
Support handle_error for pre_ping
The :meth:`.DialectEvents.handle_error` event is now moved to the
:class:`.DialectEvents` suite from the :class:`.EngineEvents` suite, and
now participates in the connection pool "pre ping" event for those dialects
that make use of disconnect codes in order to detect if the database is
live. This allows end-user code to alter the state of "pre ping". Note that
this does not include dialects which contain a native "ping" method such as
that of psycopg2 or most MySQL dialects.
Fixes: #5648
Change-Id: I353d84a4f66f309d2467b7e67621db6b8c70411e
Diffstat (limited to 'lib/sqlalchemy/engine/base.py')
-rw-r--r-- | lib/sqlalchemy/engine/base.py | 50 |
1 files changed, 38 insertions, 12 deletions
diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index b2bdd6a8d..fdccf076d 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -1960,15 +1960,14 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): newraise = None - if ( - self._has_events or self.engine._has_events - ) and not self._execution_options.get( + if (self.dialect._has_events) and not self._execution_options.get( "skip_user_error_events", False ): ctx = ExceptionContextImpl( e, sqlalchemy_exception, self.engine, + self.dialect, self, cursor, statement, @@ -1978,7 +1977,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): invalidate_pool_on_disconnect, ) - for fn in self.dispatch.handle_error: + for fn in self.dialect.dispatch.handle_error: try: # handler returns an exception; # call next handler in a chain @@ -2040,13 +2039,19 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): @classmethod def _handle_dbapi_exception_noconnection( - cls, e: BaseException, dialect: Dialect, engine: Engine + cls, + e: BaseException, + dialect: Dialect, + engine: Optional[Engine] = None, + is_disconnect: Optional[bool] = None, + invalidate_pool_on_disconnect: bool = True, ) -> NoReturn: exc_info = sys.exc_info() - is_disconnect = isinstance( - e, dialect.loaded_dbapi.Error - ) and dialect.is_disconnect(e, None, None) + if is_disconnect is None: + is_disconnect = isinstance( + e, dialect.loaded_dbapi.Error + ) and dialect.is_disconnect(e, None, None) should_wrap = isinstance(e, dialect.loaded_dbapi.Error) @@ -2056,28 +2061,32 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): None, cast(Exception, e), dialect.loaded_dbapi.Error, - hide_parameters=engine.hide_parameters, + hide_parameters=engine.hide_parameters + if engine is not None + else False, connection_invalidated=is_disconnect, + dialect=dialect, ) else: sqlalchemy_exception = None newraise = None - if engine._has_events: + if dialect._has_events: ctx = ExceptionContextImpl( e, sqlalchemy_exception, engine, + dialect, None, None, None, None, None, is_disconnect, - True, + invalidate_pool_on_disconnect, ) - for fn in engine.dispatch.handle_error: + for fn in dialect.dispatch.handle_error: try: # handler returns an exception; # call next handler in a chain @@ -2121,11 +2130,27 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): class ExceptionContextImpl(ExceptionContext): """Implement the :class:`.ExceptionContext` interface.""" + __slots__ = ( + "connection", + "engine", + "dialect", + "cursor", + "statement", + "parameters", + "original_exception", + "sqlalchemy_exception", + "chained_exception", + "execution_context", + "is_disconnect", + "invalidate_pool_on_disconnect", + ) + def __init__( self, exception: BaseException, sqlalchemy_exception: Optional[exc.StatementError], engine: Optional[Engine], + dialect: Dialect, connection: Optional[Connection], cursor: Optional[DBAPICursor], statement: Optional[str], @@ -2135,6 +2160,7 @@ class ExceptionContextImpl(ExceptionContext): invalidate_pool_on_disconnect: bool, ): self.engine = engine + self.dialect = dialect self.connection = connection self.sqlalchemy_exception = sqlalchemy_exception self.original_exception = exception |