Let others listen to SQLAlchemy errors
SQLAlchemy has 2 options of implementing error event listener. It can either raise exception directly or it can return exception into chain. With the first option all other handlers are ignored (ref: http://docs.sqlalchemy.org/en/latest/core/events.html?highlight=context#sqlalchemy.events.ConnectionEvents.handle_error) OSProfiler is interested to subscribe to SQLAlchemy error events. However with the current approach only Oslo.DB gets the events. Change-Id: Ia6bccd5af5f2e38f4333f1cc435f6bb9c12bc09f Related-Bug: 1706299
This commit is contained in:
parent
2af0348d26
commit
d77af64d8e
|
@ -475,11 +475,11 @@ def handler(context):
|
|||
if isinstance(
|
||||
dbe, exception.DBConnectionError):
|
||||
context.is_disconnect = True
|
||||
raise
|
||||
return dbe
|
||||
|
||||
|
||||
def register_engine(engine):
|
||||
event.listen(engine, "handle_error", handler)
|
||||
event.listen(engine, "handle_error", handler, retval=True)
|
||||
|
||||
@event.listens_for(engine, "rollback_savepoint")
|
||||
def rollback_savepoint(conn, name, context):
|
||||
|
|
|
@ -1496,3 +1496,36 @@ class TestDBConnectPingWrapping(TestsExceptionFilter):
|
|||
self.OperationalError('%d MySQL server has gone away' % code),
|
||||
is_disconnect=False
|
||||
)
|
||||
|
||||
|
||||
class TestsErrorHandler(TestsExceptionFilter):
|
||||
def test_multiple_error_handlers(self):
|
||||
handler = mock.MagicMock(return_value=None)
|
||||
sqla.event.listen(self.engine, "handle_error", handler, retval=True)
|
||||
|
||||
# cause an error in DB API
|
||||
self._run_test(
|
||||
"mysql", "select you_made_a_programming_error",
|
||||
self.ProgrammingError("Error 123, you made a mistake"),
|
||||
exception.DBError
|
||||
)
|
||||
|
||||
# expect custom handler to be called together with oslo.db's one
|
||||
self.assertEqual(1, handler.call_count,
|
||||
'Custom handler should be called')
|
||||
|
||||
def test_chained_exceptions(self):
|
||||
class CustomError(Exception):
|
||||
pass
|
||||
|
||||
def handler(context):
|
||||
return CustomError('Custom Error')
|
||||
|
||||
sqla.event.listen(self.engine, "handle_error", handler, retval=True)
|
||||
|
||||
# cause an error in DB API, expect exception from custom handler
|
||||
self._run_test(
|
||||
"mysql", "select you_made_a_programming_error",
|
||||
self.ProgrammingError("Error 123, you made a mistake"),
|
||||
CustomError
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue