我在我的代码中有这个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。如何将自定义消息附加到错误?我尝试以下代码,但失败,由于错误,ValueError实例,不可调用:

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

当前回答

更新:对于Python 3,检查Ben的答案


将一条消息附加到当前异常并重新引发: (外面的try/except只是为了展示效果)

对于python 2。其中X >=6:

try:
    try:
      raise ValueError  # something bad...
    except ValueError as err:
      err.message=err.message+" hello"
      raise              # re-raise current exception
except ValueError as e:
    print(" got error of type "+ str(type(e))+" with message " +e.message)

如果err是从ValueError派生的,这也会做正确的事情。例如UnicodeDecodeError。

请注意,您可以添加任何您喜欢的错误。例如err.problematic_array=[1,2,3]。


编辑:@Ducan在注释中指出,上述内容不适用于python 3,因为.message不是ValueError的成员。相反,你可以使用这个(有效的python 2.6或更高版本或3.x):

try:
    try:
      raise ValueError
    except ValueError as err:
       if not err.args: 
           err.args=('',)
       err.args = err.args + ("hello",)
       raise 
except ValueError as e:
    print(" error was "+ str(type(e))+str(e.args))

Edit2:

根据目的,您还可以选择在自己的变量名下添加额外的信息。对于python2和python3:

try:
    try:
      raise ValueError
    except ValueError as err:
       err.extra_info = "hello"
       raise 
except ValueError as e:
    print(" error was "+ str(type(e))+str(e))
    if 'extra_info' in dir(e):
       print e.extra_info

其他回答

如果你想自定义错误类型,你可以做的一件简单的事情就是基于ValueError定义一个错误类。

当前的答案对我来说并不是很好,如果没有重新捕获异常,则不会显示附加的消息。

但是像下面这样做既保持跟踪,又显示附加的消息,不管是否重新捕获异常。

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中没有尝试过)

这是我在Python 2.7和3中用来修改异常消息的函数。X,同时保留原始的回溯。需要6个

def reraise_modify(caught_exc, append_msg, prepend=False):
    """Append message to exception while preserving attributes.

    Preserves exception class, and exception traceback.

    Note:
        This function needs to be called inside an except because
        `sys.exc_info()` requires the exception context.

    Args:
        caught_exc(Exception): The caught exception object
        append_msg(str): The message to append to the caught exception
        prepend(bool): If True prepend the message to args instead of appending

    Returns:
        None

    Side Effects:
        Re-raises the exception with the preserved data / trace but
        modified message
    """
    ExceptClass = type(caught_exc)
    # Keep old traceback
    traceback = sys.exc_info()[2]
    if not caught_exc.args:
        # If no args, create our own tuple
        arg_list = [append_msg]
    else:
        # Take the last arg
        # If it is a string
        # append your message.
        # Otherwise append it to the
        # arg list(Not as pretty)
        arg_list = list(caught_exc.args[:-1])
        last_arg = caught_exc.args[-1]
        if isinstance(last_arg, str):
            if prepend:
                arg_list.append(append_msg + last_arg)
            else:
                arg_list.append(last_arg + append_msg)
        else:
            arg_list += [last_arg, append_msg]
    caught_exc.args = tuple(arg_list)
    six.reraise(ExceptClass,
                caught_exc,
                traceback)

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

这招对我很管用:

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)

上面提出的许多解决方案再次引发异常,这被认为是一种糟糕的做法。像这样简单的东西就可以了

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

因此,您将首先打印错误消息,然后引发堆栈跟踪,或者您可以简单地通过sys.exit(1)退出,而根本不显示错误消息。