在不引发异常的情况下指定异常的上下文(“ cause”)

时间:2020-04-06 16:33:17

标签: python python-3.x exception constructor

我们正在使用通过引发异常(SnafuException)来表示常见故障状态(找不到资源)的库。我们倾向于使用一种模式来处理此问题,该模式因使用情况而有所不同:

try:
    foo()
except SnafuException as se:
    log.exception("message", exc_info=se)
    raise FubarException("message")

据我了解,log.exception不需要设置exc_info = se,但是这些消息可能会降级。

这很干净,但是我现在处于一种情况下,我希望其调用方告诉特定函数如何处理异常。

def utility(data: Data,
            handler: Callable[[SnafuException], Exception] = default_handler):
    try:
        work_in_progress = foo(data)
    except SnafuException as se:
        raise handler(se)
    return finish(work_in_progress)

问题出在写default_handler;它需要返回异常,我希望返回的异常具有参数se作为父项(上下文或原因)。鉴于工作的性质(我们是一支庞大的团队,还有其他团队可能会在与我们通常管理的相同的仓库中开展工作),我想要一个记录在某处的解决方案

我该如何写return FubarException("message", cause=se)

某些选项可能还可以,但我不满意:

  • 从处理程序内部提升。这将使得难以传递lambda作为处理程序。
  • 在处理程序外部分配上下文。这可能很好用,但是在我看来,分配上下文是处理程序工作的一部分,因此应该在处理程序内部进行。
  • 从字面上分配handler_return_value.__cause__ = se到处理程序中。这是documented in PEP 3134,所以很好。但是它使用的是protected / magic属性,PEP是2005年的,所以如果这是“正确”的方法,那么我希望它现在已经在其他地方有记载。
  • try: ... except: ...移动到处理程序函数中,这将以“动作”函数foo作为参数。当然,这将尽可能地完全捆绑所讨论的模式,但是我担心它会混淆执行的主要流程,不够灵活,无法在许多情况下使用,并且/或者将需要大量的lambda表达式。 / li>

有什么建议吗?

0 个答案:

没有答案