希望我的代码引发特定类型或错误,但打印原始错误

Posted

技术标签:

【中文标题】希望我的代码引发特定类型或错误,但打印原始错误【英文标题】:Want my code to raise a specific type or error, but print the orginal error 【发布时间】:2019-07-25 05:20:48 【问题描述】:

所以假设我有一些代码会引发任何类型或错误。我希望我的代码改为引发 AssertionError,但打印出原始消息将与原始错误一起打印。我该怎么做?

(示例)

原始错误: TypeError: '>' 在 'str' 和 'int' 的实例之间不支持

自定义错误:AssertionError: exception = TypeError: '>' not supported between 'str' and 'int'

【问题讨论】:

【参考方案1】:

您必须捕获引发的异常,然后引发您想要的任何类型。由于您提到要捕获 any 类型的错误,因此您必须使用 Exception 类作为您的捕获。

但是,我要指出,这通常是不好的做法,因为您通常只想捕获您预期会遇到的特定错误。但是如果你最终还是抛出了一个错误,我想这并不可怕。但也让我想知道这段代码的具体目标是什么。反正..

捕捉任何东西

try...except Exception as e

引发首选错误

raise AssertionError()

收到消息

e.message

获取类型

type(e)

把它们放在一起:

try:
    # some code that raises an error
    g = 10 + '11'
except Exception as e:
    raise AssertionError(': '.format(type(e), e.message))

输出将是:

<type 'exceptions.TypeError'>: unsupported operand type(s) for +: 'int' and 'str'

这可以被清理以摆脱 type(e) 的丑陋输出,但通常这是包含错误类型及其相应消息的方式。

【讨论】:

谢谢,您的回答有所帮助,但我也想知道原来的错误类型是什么。在这里,原来是一个 TypeError,那我怎么知道呢? 哦,是的,您可以使用type(e) 访问它。我将编辑答案以包含它。 @J_H 也有一个更清洁的解决方案。我相信该功能是 Python 3 特有的,但那是您标记的版本,所以我会使用它【参考方案2】:

您正在寻找 from syntax(在 Python 3 中引入),它可以让您将特定于应用程序的异常包装在基本异常周围。 这是一个例子:

>>> try:
...     1 > '1'
... except TypeError as e:
...     raise AssertionError() from e
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
TypeError: '>' not supported between instances of 'int' and 'str'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
AssertionError

您可以在创建新异常时提供包含诊断消息的字符串。 最好定义自己的应用程序特定异常,而不是回收 AssertionError。 如果您定义了多个,请将其中一个设为 [grand] 父级,并让其他异常从该祖先继承。 这使调用者可以方便地捕获细粒度或粗粒度的错误。

有一个PEP 描述了进一步的考虑。

【讨论】:

【参考方案3】:

您还可以通过设置 __suppress_context__ = True 来隐藏原始回溯,并进行一些格式化以满足您对预期输出的需求:

try:
    a = '1' > 1
except Exception as exc:
    assertion_exc = AssertionError('exception = : '.format(type(exc).__name__, str(exc)))
    assertion_exc.__suppress_context__ = True # comment this line to see full traceback
    raise assertion_exc

完整输出:

Traceback (most recent call last):
  File "./file.py", line 8, in <module>
    raise assertion_exc
AssertionError: exception = TypeError: '>' not supported between instances of 'str' and 'int'

【讨论】:

我希望我的例外情况更笼统。在我的示例中,TypeError 只是可能的错误类型之一的示例。那么我怎么能包含任何类型的错误呢? except Exception 会捕捉到任何东西。更新了我的答案。

以上是关于希望我的代码引发特定类型或错误,但打印原始错误的主要内容,如果未能解决你的问题,请参考以下文章

在表单中的特定字段上引发 Django 中的错误

在 node.js 中引发错误

错误:“在此上下文中仅支持原始类型或枚举类型”

我正在尝试检查电子邮件是不是已存在于数据库中或不在数据库中,但我的代码会引发错误

引用 SQL 数据库项目 (SQLCLR) 引发“找不到类型或命名空间”错误

如果我的模板类型首先作为 lambda 参数出现,MSVC 会引发一个奇怪的错误