如何在Python中使用自定义消息引发相同异常?

269

我在代码中有这个try块:

try:
    do_something_that_might_raise_an_exception()
except ValueError as err:
    errmsg = 'My custom error message.'
    raise ValueError(errmsg)

严格来说,我实际上是在引发另一个 ValueError,而不是由do_something...()抛出的ValueError,此时称其为err。我该如何将自定义消息附加到err? 我尝试以下代码但失败了,因为err是一个ValueError 实例,不可调用:

try:
    do_something_that_might_raise_an_exception()
except ValueError as err:
    errmsg = 'My custom error message.'
    raise err(errmsg)

15
@Hamish,当调试时,附加额外信息和重新引发异常可以非常有帮助。 - Johan Lundberg
@Johan 当然没问题 - 这就是堆栈跟踪的作用。我不太明白为什么你要编辑现有的错误消息而不是引发一个新的错误。 - Hamish
@Hamish。当然,你可以添加其他内容。关于你的问题,请看一下我的回答和UnicodeDecodeError的示例。如果你对此有评论,也许可以在我的回答中评论。 - Johan Lundberg
3
@Kit,现在已经是2020年,Python 3 已经普及了。为什么不把采纳的答案改成Ben的答案呢 :-) - mit
1
@mit 现在是2023年,我已经更改了正确答案 :D - Kit
显示剩余2条评论
17个回答

1

当前的答案对我来说不太有效,如果异常没有被重新捕获,追加的消息就不会显示。

但是像下面这样做,无论是否重新捕获异常,都可以保留跟踪并显示追加的消息。

try:
  raise ValueError("Original message")
except ValueError as err:
  t, v, tb = sys.exc_info()
  raise t, ValueError(err.message + " Appended Info"), tb

我使用的是Python 2.7,尚未在Python 3中尝试过。


1
Python 3内置异常具有"strerror"字段:
except ValueError as err:
  err.strerror = "New error message"
  raise err

这似乎不起作用。你有什么遗漏吗? - MasayoMusic
4
“strerror”实例变量是特定于“OSError”异常的。由于大多数“ValueError”异常都没有定义此变量,因此这种非解决方案通常会引发不可读的异常,因此对程序是有害的。哈哈,兄弟。 - Cecil Curry

1

以上解决方案都没有完全满足我的需求,我想在错误信息的第一部分添加一些信息,即我希望我的用户首先看到我的自定义消息。

这对我有用:

exception_raised = False
try:
    do_something_that_might_raise_an_exception()
except ValueError as e:
    message = str(e)
    exception_raised = True

if exception_raised:
    message_to_prepend = "Custom text"
    raise ValueError(message_to_prepend + message)

-1

我尝试了@RobinL的这个简洁版本,也起作用了:

try:
    do_something_that_might_raise_an_exception()
except ValueError as e:
    error_message = 'My error message'
    raise ValueError(f'Custom text {error_message}')

-2
在前面添加自定义文本消息的情况下引发相同的错误。 (编辑- 对不起,实际上与https://dev59.com/vmox5IYBdhLWcg3whUgV#65494175相同,为什么会有像10个(点赞)“解决方案”,它们根本没有回答所提出的问题?)
    try:
       <code causing exception>
    except Exception as e:
        e.args = (f"My custom text. Original Exception text: {'-'.join(e.args)}",)
        raise

-3

上面提出的许多解决方案都会再次引发异常,这被认为是一种不好的做法。像这样简单的代码就可以完成任务。

try:
    import settings
except ModuleNotFoundError:
    print("Something meaningfull\n")
    raise 

所以你首先会打印错误信息,然后引发堆栈跟踪,或者你可以通过sys.exit(1)直接退出,根本不显示错误消息。

-7

如果你想自定义错误类型,一个简单的方法是基于ValueError定义一个错误类。


1
在这种情况下,那会如何有所帮助? - Johan Lundberg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接