我想捕获特定的异常,例如UniqueViolationsqlalchemy 上的异常。
但 sqlalchemy 仅通过IntegrityError.
所以我用下面的代码捕获了特定的异常。
except sqlalchemy.exc.IntegrityError as e:
from psycopg2 import errors
if isinstance(e.orig, errors.UniqueViolation):
pass
elif isinstance(e.orig, errors.ForeignKeyViolation):
pass
Run Code Online (Sandbox Code Playgroud)
但看起来并不优雅。
我不想使用 if 语句只是捕获特定的异常名称。
有什么办法可以解决这个问题吗?
谢谢。
这只是一个想法 - 我根本没有测试过 - 但也许上下文管理器可以做你想做的事。例如,如果您希望特定查询引发原始异常,则使用with raise_orig(): query().
from contextlib import contextmanager
from sqlalchemy.exc import StatementError
@contextmanager
def raise_orig():
try:
yield
except StatementError as stmt_exc:
raise stmt_exc.orig
def query():
raise StatementError(
message="Message from SQLAlchemy",
statement="SELECT 1",
params=(),
orig=RuntimeError("The original exception instance"),
)
if __name__ == "__main__":
with raise_orig():
query()
Run Code Online (Sandbox Code Playgroud)
这是引发的回溯:
Traceback (most recent call last):
File "raise_orig.py", line 7, in raise_orig
yield
File "raise_orig.py", line 23, in <module>
query()
File "raise_orig.py", line 17, in query
orig=RuntimeError("The original exception instance"),
sqlalchemy.exc.StatementError: Message from SQLAlchemy
[SQL: SELECT 1]
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "raise_orig.py", line 23, in <module>
query()
File "C:\Users\peter_000\AppData\Local\Programs\Python\Python36\Lib\contextlib.py", line 99, in __exit__
self.gen.throw(type, value, traceback)
File "raise_orig.py", line 9, in raise_orig
raise stmt_exc.orig
RuntimeError: The original exception instance
Run Code Online (Sandbox Code Playgroud)
我选择测试 forStatementError因为这是具有该属性的最主要的异常类型orig。
并不完美,因为回溯将比现在更加复杂,但至少应该允许您捕获特定类型。
您还可以使用上下文管理器模式来抽象异常类型检查和处理,这样您就不需要在任何地方重复它(那么它只需要在一个地方看起来很难看!):
Traceback (most recent call last):
File "raise_orig.py", line 7, in raise_orig
yield
File "raise_orig.py", line 23, in <module>
query()
File "raise_orig.py", line 17, in query
orig=RuntimeError("The original exception instance"),
sqlalchemy.exc.StatementError: Message from SQLAlchemy
[SQL: SELECT 1]
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "raise_orig.py", line 23, in <module>
query()
File "C:\Users\peter_000\AppData\Local\Programs\Python\Python36\Lib\contextlib.py", line 99, in __exit__
self.gen.throw(type, value, traceback)
File "raise_orig.py", line 9, in raise_orig
raise stmt_exc.orig
RuntimeError: The original exception instance
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5330 次 |
| 最近记录: |