diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2011-06-22 11:45:28 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2011-06-22 11:45:28 -0400 |
commit | e821573a2470d42c3caa8988b93503353b1a5da2 (patch) | |
tree | f27b1c651b4cd59ee1c7eca1d344364e0260b6c9 /lib/sqlalchemy/exc.py | |
parent | 7173d11ba2ad2275951c973a784b9f28396dea90 (diff) | |
download | sqlalchemy-e821573a2470d42c3caa8988b93503353b1a5da2.tar.gz |
- Added mixin class sqlalchemy.ext.DontWrapMixin.
User-defined exceptions of this type are never
wrapped in StatementException when they
occur in the context of a statement
execution.
- StatementException wrapping will display the
original exception class in the message.
Diffstat (limited to 'lib/sqlalchemy/exc.py')
-rw-r--r-- | lib/sqlalchemy/exc.py | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/lib/sqlalchemy/exc.py b/lib/sqlalchemy/exc.py index 3e88ee3a6..a7ea5b0e2 100644 --- a/lib/sqlalchemy/exc.py +++ b/lib/sqlalchemy/exc.py @@ -12,6 +12,7 @@ result of DBAPI exceptions are all subclasses of """ +import traceback class SQLAlchemyError(Exception): """Generic error class.""" @@ -98,6 +99,26 @@ class UnboundExecutionError(InvalidRequestError): """SQL was attempted without a database connection to execute it on.""" +class DontWrapMixin(object): + """A mixin class which, when applied to a user-defined Exception class, + will not be wrapped inside of :class:`.StatementError` if the error is + emitted within the process of executing a statement. + + E.g.:: + from sqlalchemy.exc import DontWrapMixin + + class MyCustomException(Exception, DontWrapMixin): + pass + + class MySpecialType(TypeDecorator): + impl = String + + def process_bind_param(self, value, dialect): + if value == 'invalid': + raise MyCustomException("invalid!") + + """ + # Moved to orm.exc; compatibility definition installed by orm import until 0.6 UnmappedColumnError = None @@ -160,14 +181,18 @@ class DBAPIError(StatementError): connection_invalidated=False): # Don't ever wrap these, just return them directly as if # DBAPIError didn't exist. - if isinstance(orig, (KeyboardInterrupt, SystemExit)): + if isinstance(orig, (KeyboardInterrupt, SystemExit, DontWrapMixin)): return orig if orig is not None: # not a DBAPI error, statement is present. # raise a StatementError if not isinstance(orig, dbapi_base_err) and statement: - return StatementError(str(orig), statement, params, orig) + return StatementError( + "%s (original cause: %s)" % ( + str(orig), + traceback.format_exception_only(orig.__class__, orig)[-1].strip() + ), statement, params, orig) name, glob = orig.__class__.__name__, globals() if name in glob and issubclass(glob[name], DBAPIError): |