class_docstr: event interface for execution-replacement functions.
  
  These events allow direct instrumentation and replacement
  of key dialect functions which interact with the DBAPI.
  
  .. note::
  
      :class:`.DialectEvents` hooks should be considered **semi-public**
      and experimental.
      These hooks are not for general use and are only for those situations
      where intricate re-statement of DBAPI mechanics must be injected onto
      an existing dialect.  For general-use statement-interception events,
      please use the :class:`_events.ConnectionEvents` interface.
  
  .. seealso::
  
      :meth:`_events.ConnectionEvents.before_cursor_execute`
  
      :meth:`_events.ConnectionEvents.before_execute`
  
      :meth:`_events.ConnectionEvents.after_cursor_execute`
  
      :meth:`_events.ConnectionEvents.after_execute`
class_docstr_tok: ["event","interface","for","execution-replacement","functions",".","These","events","allow","direct","instrumentation","and","replacement","of","key","dialect","functions","which","interact","with","the","DBAPI",".","..","note",":",":",":","class",":","`",".DialectEvents","`","hooks","should","be","considered","*","*","semi-public","*","*","and","experimental",".","These","hooks","are","not","for","general","use","and","are","only","for","those","situations","where","intricate","re-statement","of","DBAPI","mechanics","must","be","injected","onto","an","existing","dialect",".","For","general-use","statement-interception","events",",","please","use","the",":","class",":","`","_events.ConnectionEvents","`","interface",".","..","seealso",":",":",":","meth",":","`","_events.ConnectionEvents.before_cursor_execute","`",":","meth",":","`","_events.ConnectionEvents.before_execute","`",":","meth",":","`","_events.ConnectionEvents.after_cursor_execute","`",":","meth",":","`","_events.ConnectionEvents.after_execute","`"]
docstr: Intercept all exceptions processed by the
  :class:`_engine.Dialect`, typically but not limited to those
  emitted within the scope of a :class:`_engine.Connection`.
  
  .. versionchanged:: 2.0 the :meth:`.DialectEvents.handle_error` event
     is moved to the :class:`.DialectEvents` class, moved from the
     :class:`.ConnectionEvents` class, so that it may also participate in
     the "pre ping" operation configured with the
     :paramref:`_sa.create_engine.pool_pre_ping` parameter. The event
     remains registered by using the :class:`_engine.Engine` as the event
     target, however note that using the :class:`_engine.Connection` as
     an event target for :meth:`.DialectEvents.handle_error` is no longer
     supported.
  
  This includes all exceptions emitted by the DBAPI as well as
  within SQLAlchemy's statement invocation process, including
  encoding errors and other statement validation errors.  Other areas
  in which the event is invoked include transaction begin and end,
  result row fetching, cursor creation.
  
  Note that :meth:`.handle_error` may support new kinds of exceptions
  and new calling scenarios at *any time*.  Code which uses this
  event must expect new calling patterns to be present in minor
  releases.
  
  To support the wide variety of members that correspond to an exception,
  as well as to allow extensibility of the event without backwards
  incompatibility, the sole argument received is an instance of
  :class:`.ExceptionContext`.   This object contains data members
  representing detail about the exception.
  
  Use cases supported by this hook include:
  
  * read-only, low-level exception handling for logging and
    debugging purposes
  * Establishing whether a DBAPI connection error message indicates
    that the database connection needs to be reconnected, including
    for the "pre_ping" handler used by **some** dialects
  * Establishing or disabling whether a connection or the owning
    connection pool is invalidated or expired in response to a
    specific exception
  * exception re-writing
  
  The hook is called while the cursor from the failed operation
  (if any) is still open and accessible.   Special cleanup operations
  can be called on this cursor; SQLAlchemy will attempt to close
  this cursor subsequent to this hook being invoked.
  
  As of SQLAlchemy 2.0, the "pre_ping" handler enabled using the
  :paramref:`_sa.create_engine.pool_pre_ping` parameter will also
  participate in the :meth:`.handle_error` process, **for those dialects
  that rely upon disconnect codes to detect database liveness**. Note
  that some dialects such as psycopg, psycopg2, and most MySQL dialects
  make use of a native ``ping()`` method supplied by the DBAPI which does
  not make use of disconnect codes.
  
  .. versionchanged:: 2.0.0 The :meth:`.DialectEvents.handle_error`
     event hook participates in connection pool "pre-ping" operations.
     Within this usage, the :attr:`.ExceptionContext.engine` attribute
     will be ``None``, however the :class:`.Dialect` in use is always
     available via the :attr:`.ExceptionContext.dialect` attribute.
  
  .. versionchanged:: 2.0.5 Added :attr:`.ExceptionContext.is_pre_ping`
     attribute which will be set to ``True`` when the
     :meth:`.DialectEvents.handle_error` event hook is triggered within
     a connection pool pre-ping operation.
  
  .. versionchanged:: 2.0.5 An issue was repaired that allows for the
     PostgreSQL ``psycopg`` and ``psycopg2`` drivers, as well as all
     MySQL drivers, to properly participate in the
     :meth:`.DialectEvents.handle_error` event hook during
     connection pool "pre-ping" operations; previously, the
     implementation was non-working for these drivers.
  
  
  A handler function has two options for replacing
  the SQLAlchemy-constructed exception into one that is user
  defined.   It can either raise this new exception directly, in
  which case all further event listeners are bypassed and the
  exception will be raised, after appropriate cleanup as taken
  place::
  
      @event.listens_for(Engine, "handle_error")
      def handle_exception(context):
          if isinstance(context.original_exception,
              psycopg2.OperationalError) and \
              "failed" in str(context.original_exception):
              raise MySpecialException("failed operation")
  
  .. warning::  Because the
     :meth:`_events.DialectEvents.handle_error`
     event specifically provides for exceptions to be re-thrown as
     the ultimate exception raised by the failed statement,
     **stack traces will be misleading** if the user-defined event
     handler itself fails and throws an unexpected exception;
     the stack trace may not illustrate the actual code line that
     failed!  It is advised to code carefully here and use
     logging and/or inline debugging if unexpected exceptions are
     occurring.
  
  Alternatively, a "chained" style of event handling can be
  used, by configuring the handler with the ``retval=True``
  modifier and returning the new exception instance from the
  function.  In this case, event handling will continue onto the
  next handler.   The "chained" exception is available using
  :attr:`.ExceptionContext.chained_exception`::
  
      @event.listens_for(Engine, "handle_error", retval=True)
      def handle_exception(context):
          if context.chained_exception is not None and \
              "special" in context.chained_exception.message:
              return MySpecialException("failed",
                  cause=context.chained_exception)
  
  Handlers that return ``None`` may be used within the chain; when
  a handler returns ``None``, the previous exception instance,
  if any, is maintained as the current exception that is passed onto the
  next handler.
  
  When a custom exception is raised or returned, SQLAlchemy raises
  this new exception as-is, it is not wrapped by any SQLAlchemy
  object.  If the exception is not a subclass of
  :class:`sqlalchemy.exc.StatementError`,
  certain features may not be available; currently this includes
  the ORM's feature of adding a detail hint about "autoflush" to
  exceptions raised within the autoflush process.
  
  :param context: an :class:`.ExceptionContext` object.  See this
   class for details on all available members.
  
  
  .. seealso::
  
      :ref:`pool_new_disconnect_codes`
docstr_tok: ["Intercept","all","exceptions","processed","by","the",":","class",":","`","_engine.Dialect","`",",","typically","but","not","limited","to","those","emitted","within","the","scope","of","a",":","class",":","`","_engine.Connection","`",".","..","versionchanged",":",":","2.0","the",":","meth",":","`",".DialectEvents.handle_error","`","event","is","moved","to","the",":","class",":","`",".DialectEvents","`","class",",","moved","from","the",":","class",":","`",".ConnectionEvents","`","class",",","so","that","it","may","also","participate","in","the","``","pre","ping","''","operation","configured","with","the",":","paramref",":","`","_sa.create_engine.pool_pre_ping","`","parameter",".","The","event","remains","registered","by","using","the",":","class",":","`","_engine.Engine","`","as","the","event","target",",","however","note","that","using","the",":","class",":","`","_engine.Connection","`","as","an","event","target","for",":","meth",":","`",".DialectEvents.handle_error","`","is","no","longer","supported",".","This","includes","all","exceptions","emitted","by","the","DBAPI","as","well","as","within","SQLAlchemy","'s","statement","invocation","process",",","including","encoding","errors","and","other","statement","validation","errors",".","Other","areas","in","which","the","event","is","invoked","include","transaction","begin","and","end",",","result","row","fetching",",","cursor","creation",".","Note","that",":","meth",":","`",".handle_error","`","may","support","new","kinds","of","exceptions","and","new","calling","scenarios","at","*","any","time","*",".","Code","which","uses","this","event","must","expect","new","calling","patterns","to","be","present","in","minor","releases",".","To","support","the","wide","variety","of","members","that","correspond","to","an","exception",",","as","well","as","to","allow","extensibility","of","the","event","without","backwards","incompatibility",",","the","sole","argument","received","is","an","instance","of",":","class",":","`",".ExceptionContext","`",".","This","object","contains","data","members","representing","detail","about","the","exception",".","Use","cases","supported","by","this","hook","include",":","*","read-only",",","low-level","exception","handling","for","logging","and","debugging","purposes","*","Establishing","whether","a","DBAPI","connection","error","message","indicates","that","the","database","connection","needs","to","be","reconnected",",","including","for","the","``","pre_ping","''","handler","used","by","*","*","some","*","*","dialects","*","Establishing","or","disabling","whether","a","connection","or","the","owning","connection","pool","is","invalidated","or","expired","in","response","to","a","specific","exception","*","exception","re-writing","The","hook","is","called","while","the","cursor","from","the","failed","operation","(","if","any",")","is","still","open","and","accessible",".","Special","cleanup","operations","can","be","called","on","this","cursor",";","SQLAlchemy","will","attempt","to","close","this","cursor","subsequent","to","this","hook","being","invoked",".","As","of","SQLAlchemy","2.0",",","the","``","pre_ping","''","handler","enabled","using","the",":","paramref",":","`","_sa.create_engine.pool_pre_ping","`","parameter","will","also","participate","in","the",":","meth",":","`",".handle_error","`","process",",","*","*","for","those","dialects","that","rely","upon","disconnect","codes","to","detect","database","liveness","*","*",".","Note","that","some","dialects","such","as","psycopg",",","psycopg2",",","and","most","MySQL","dialects","make","use","of","a","native","``","ping","(",")","``","method","supplied","by","the","DBAPI","which","does","not","make","use","of","disconnect","codes",".","..","versionchanged",":",":","2.0.0","The",":","meth",":","`",".DialectEvents.handle_error","`","event","hook","participates","in","connection","pool","``","pre-ping","''","operations",".","Within","this","usage",",","the",":","attr",":","`",".ExceptionContext.engine","`","attribute","will","be","``","None","``",",","however","the",":","class",":","`",".Dialect","`","in","use","is","always","available","via","the",":","attr",":","`",".ExceptionContext.dialect","`","attribute",".","..","versionchanged",":",":","2.0.5","Added",":","attr",":","`",".ExceptionContext.is_pre_ping","`","attribute","which","will","be","set","to","``","True","``","when","the",":","meth",":","`",".DialectEvents.handle_error","`","event","hook","is","triggered","within","a","connection","pool","pre-ping","operation",".","..","versionchanged",":",":","2.0.5","An","issue","was","repaired","that","allows","for","the","PostgreSQL","``","psycopg","``","and","``","psycopg2","``","drivers",",","as","well","as","all","MySQL","drivers",",","to","properly","participate","in","the",":","meth",":","`",".DialectEvents.handle_error","`","event","hook","during","connection","pool","``","pre-ping","''","operations",";","previously",",","the","implementation","was","non-working","for","these","drivers",".","A","handler","function","has","two","options","for","replacing","the","SQLAlchemy-constructed","exception","into","one","that","is","user","defined",".","It","can","either","raise","this","new","exception","directly",",","in","which","case","all","further","event","listeners","are","bypassed","and","the","exception","will","be","raised",",","after","appropriate","cleanup","as","taken","place",":",":","@","event.listens_for","(","Engine",",","``","handle_error","''",")","def","handle_exception","(","context",")",":","if","isinstance","(","context.original_exception",",","psycopg2.OperationalError",")","and","\\","``","failed","''","in","str","(","context.original_exception",")",":","raise","MySpecialException","(","``","failed","operation","''",")","..","warning",":",":","Because","the",":","meth",":","`","_events.DialectEvents.handle_error","`","event","specifically","provides","for","exceptions","to","be","re-thrown","as","the","ultimate","exception","raised","by","the","failed","statement",",","*","*","stack","traces","will","be","misleading","*","*","if","the","user-defined","event","handler","itself","fails","and","throws","an","unexpected","exception",";","the","stack","trace","may","not","illustrate","the","actual","code","line","that","failed","!","It","is","advised","to","code","carefully","here","and","use","logging","and\/or","inline","debugging","if","unexpected","exceptions","are","occurring",".","Alternatively",",","a","``","chained","''","style","of","event","handling","can","be","used",",","by","configuring","the","handler","with","the","``","retval=True","``","modifier","and","returning","the","new","exception","instance","from","the","function",".","In","this","case",",","event","handling","will","continue","onto","the","next","handler",".","The","``","chained","''","exception","is","available","using",":","attr",":","`",".ExceptionContext.chained_exception","`",":",":","@","event.listens_for","(","Engine",",","``","handle_error","''",",","retval=True",")","def","handle_exception","(","context",")",":","if","context.chained_exception","is","not","None","and","\\","``","special","''","in","context.chained_exception.message",":","return","MySpecialException","(","``","failed","''",",","cause=context.chained_exception",")","Handlers","that","return","``","None","``","may","be","used","within","the","chain",";","when","a","handler","returns","``","None","``",",","the","previous","exception","instance",",","if","any",",","is","maintained","as","the","current","exception","that","is","passed","onto","the","next","handler",".","When","a","custom","exception","is","raised","or","returned",",","SQLAlchemy","raises","this","new","exception","as-is",",","it","is","not","wrapped","by","any","SQLAlchemy","object",".","If","the","exception","is","not","a","subclass","of",":","class",":","`","sqlalchemy.exc.StatementError","`",",","certain","features","may","not","be","available",";","currently","this","includes","the","ORM","'s","feature","of","adding","a","detail","hint","about","``","autoflush","''","to","exceptions","raised","within","the","autoflush","process",".",":","param","context",":","an",":","class",":","`",".ExceptionContext","`","object",".","See","this","class","for","details","on","all","available","members",".","..","seealso",":",":",":","ref",":","`","pool_new_disconnect_codes","`"]
code: def handle_error(
      self, exception_context: ExceptionContext
  ) -> Optional[BaseException]:
      r"""Intercept all exceptions processed by the
          :class:`_engine.Dialect`, typically but not limited to those
          emitted within the scope of a :class:`_engine.Connection`.
  
          .. versionchanged:: 2.0 the :meth:`.DialectEvents.handle_error` event
             is moved to the :class:`.DialectEvents` class, moved from the
             :class:`.ConnectionEvents` class, so that it may also participate in
             the "pre ping" operation configured with the
             :paramref:`_sa.create_engine.pool_pre_ping` parameter. The event
             remains registered by using the :class:`_engine.Engine` as the event
             target, however note that using the :class:`_engine.Connection` as
             an event target for :meth:`.DialectEvents.handle_error` is no longer
             supported.
  
          This includes all exceptions emitted by the DBAPI as well as
          within SQLAlchemy's statement invocation process, including
          encoding errors and other statement validation errors.  Other areas
          in which the event is invoked include transaction begin and end,
          result row fetching, cursor creation.
  
          Note that :meth:`.handle_error` may support new kinds of exceptions
          and new calling scenarios at *any time*.  Code which uses this
          event must expect new calling patterns to be present in minor
          releases.
  
          To support the wide variety of members that correspond to an exception,
          as well as to allow extensibility of the event without backwards
          incompatibility, the sole argument received is an instance of
          :class:`.ExceptionContext`.   This object contains data members
          representing detail about the exception.
  
          Use cases supported by this hook include:
  
          * read-only, low-level exception handling for logging and
            debugging purposes
          * Establishing whether a DBAPI connection error message indicates
            that the database connection needs to be reconnected, including
            for the "pre_ping" handler used by **some** dialects
          * Establishing or disabling whether a connection or the owning
            connection pool is invalidated or expired in response to a
            specific exception
          * exception re-writing
  
          The hook is called while the cursor from the failed operation
          (if any) is still open and accessible.   Special cleanup operations
          can be called on this cursor; SQLAlchemy will attempt to close
          this cursor subsequent to this hook being invoked.
  
          As of SQLAlchemy 2.0, the "pre_ping" handler enabled using the
          :paramref:`_sa.create_engine.pool_pre_ping` parameter will also
          participate in the :meth:`.handle_error` process, **for those dialects
          that rely upon disconnect codes to detect database liveness**. Note
          that some dialects such as psycopg, psycopg2, and most MySQL dialects
          make use of a native ``ping()`` method supplied by the DBAPI which does
          not make use of disconnect codes.
  
          .. versionchanged:: 2.0.0 The :meth:`.DialectEvents.handle_error`
             event hook participates in connection pool "pre-ping" operations.
             Within this usage, the :attr:`.ExceptionContext.engine` attribute
             will be ``None``, however the :class:`.Dialect` in use is always
             available via the :attr:`.ExceptionContext.dialect` attribute.
  
          .. versionchanged:: 2.0.5 Added :attr:`.ExceptionContext.is_pre_ping`
             attribute which will be set to ``True`` when the
             :meth:`.DialectEvents.handle_error` event hook is triggered within
             a connection pool pre-ping operation.
  
          .. versionchanged:: 2.0.5 An issue was repaired that allows for the
             PostgreSQL ``psycopg`` and ``psycopg2`` drivers, as well as all
             MySQL drivers, to properly participate in the
             :meth:`.DialectEvents.handle_error` event hook during
             connection pool "pre-ping" operations; previously, the
             implementation was non-working for these drivers.
  
  
          A handler function has two options for replacing
          the SQLAlchemy-constructed exception into one that is user
          defined.   It can either raise this new exception directly, in
          which case all further event listeners are bypassed and the
          exception will be raised, after appropriate cleanup as taken
          place::
  
              @event.listens_for(Engine, "handle_error")
              def handle_exception(context):
                  if isinstance(context.original_exception,
                      psycopg2.OperationalError) and \
                      "failed" in str(context.original_exception):
                      raise MySpecialException("failed operation")
  
          .. warning::  Because the
             :meth:`_events.DialectEvents.handle_error`
             event specifically provides for exceptions to be re-thrown as
             the ultimate exception raised by the failed statement,
             **stack traces will be misleading** if the user-defined event
             handler itself fails and throws an unexpected exception;
             the stack trace may not illustrate the actual code line that
             failed!  It is advised to code carefully here and use
             logging and/or inline debugging if unexpected exceptions are
             occurring.
  
          Alternatively, a "chained" style of event handling can be
          used, by configuring the handler with the ``retval=True``
          modifier and returning the new exception instance from the
          function.  In this case, event handling will continue onto the
          next handler.   The "chained" exception is available using
          :attr:`.ExceptionContext.chained_exception`::
  
              @event.listens_for(Engine, "handle_error", retval=True)
              def handle_exception(context):
                  if context.chained_exception is not None and \
                      "special" in context.chained_exception.message:
                      return MySpecialException("failed",
                          cause=context.chained_exception)
  
          Handlers that return ``None`` may be used within the chain; when
          a handler returns ``None``, the previous exception instance,
          if any, is maintained as the current exception that is passed onto the
          next handler.
  
          When a custom exception is raised or returned, SQLAlchemy raises
          this new exception as-is, it is not wrapped by any SQLAlchemy
          object.  If the exception is not a subclass of
          :class:`sqlalchemy.exc.StatementError`,
          certain features may not be available; currently this includes
          the ORM's feature of adding a detail hint about "autoflush" to
          exceptions raised within the autoflush process.
  
          :param context: an :class:`.ExceptionContext` object.  See this
           class for details on all available members.
  
  
          .. seealso::
  
              :ref:`pool_new_disconnect_codes`
  
          """
  
imports: from __future__ import annotations
  import typing
  from typing import Any
  from typing import Dict
  from typing import Optional
  from typing import Tuple
  from typing import Type
  from typing import Union
  from .base import Connection
  from .base import Engine
  from .interfaces import ConnectionEventsTarget
  from .interfaces import DBAPIConnection
  from .interfaces import DBAPICursor
  from .interfaces import Dialect
  from ..None import event
  from ..None import exc
  from ..util.typing import Literal
label_desc: Use image node_id 3 for calling the DialectEvents obj's underlying member method code with example usage: obj.handle_error(exception_context) without return types