使用不同的类型和消息重新引发异常,保留现有信息 [英] Re-raise exception with a different type and message, preserving existing information

查看:191
本文介绍了使用不同的类型和消息重新引发异常,保留现有信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个模块,并希望对它可以提出的异常有一个统一的异常层次结构(例如从 FooError 继承所有 foo 模块的具体例外)。这允许模块的用户捕获这些特殊的异常,并在需要时明确地处理它们。但是,由于其他一些例外情况,提出了模块引发的许多异常;例如因为某个文件的OSError导致某些任务失败。



我需要的是包装捕获的异常,使其具有不同的类型和消息,以便通过任何捕获异常的信息可以进一步扩展传播层次结构。但我不想丢失现有的类型,消息和堆栈跟踪;这是有人试图调试问题的所有有用的信息。顶级的异常处理程序是不错的,因为我试图装饰异常,然后再进一步扩展传播堆栈,顶级处理程序太晚了。



通过从现有类型导出我的模块 foo 的特定异常类型(例如 class FooPermissionError(OSError,FooError )),但这并不会使现有的异常实例更容易地包含在新的类型中,也不会修改消息。



Python的 PEP 3134 异常链接和嵌入式追溯讨论了Python中接受的更改3.0表示链接异常对象,表示在处理现有异常时引发了一个新的异常。



我要做的是相关的:我需要它也可以在早期的Python版本中工作,而且我不需要链接,而是仅用于多态。什么是正确的方法?

解决方案

Python 3 引入异常链接(如 PEP 3134 所述)。引用一个异常作为原因引发异常:

  try:
frobnicate()
除了KeyError作为exc:
raise从$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $
$ b

因此,捕获的异常成为新异常的一部分(是原因),可用于任何代码捕获新异常。





Python 2 中,似乎这个用例没有很好的答案(如 Ian Bicking Ned Batchelder )。 Bummer。


I'm writing a module and want to have a unified exception hierarchy for the exceptions that it can raise (e.g. inheriting from a FooError abstract class for all the foo module's specific exceptions). This allows users of the module to catch those particular exceptions and handle them distinctly, if needed. But many of the exceptions raised from the module are raised because of some other exception; e.g. failing at some task because of an OSError on a file.

What I need is to "wrap" the exception caught such that it has a different type and message, so that information is available further up the propagation hierarchy by whatever catches the exception. But I don't want to lose the existing type, message, and stack trace; that's all useful information for someone trying to debug the problem. A top-level exception handler is no good, since I'm trying to decorate the exception before it makes its way further up the propagation stack, and the top-level handler is too late.

This is partly solved by deriving my module foo's specific exception types from the existing type (e.g. class FooPermissionError(OSError, FooError)), but that doesn't make it any easier to wrap the existing exception instance in a new type, nor modify the message.

Python's PEP 3134 "Exception Chaining and Embedded Tracebacks" discusses a change accepted in Python 3.0 for "chaining" exception objects, to indicate that a new exception was raised during the handling of an existing exception.

What I'm trying to do is related: I need it also working in earlier Python versions, and I need it not for chaining, but only for polymorphism. What is the right way to do this?

解决方案

Python 3 introduced exception chaining (as described in PEP 3134). This allows raising an exception, citing an existing exception as the "cause":

try:
    frobnicate()
except KeyError as exc:
    raise ValueError("Bad grape") from exc

The caught exception thereby becomes part of (is the "cause of") the new exception, and is available to whatever code catches the new exception.


In Python 2, it appears this use case has no good answer (as described by Ian Bicking and Ned Batchelder). Bummer.

这篇关于使用不同的类型和消息重新引发异常,保留现有信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆