首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java的Throwable.addSuppressed()

Java的Throwable.addSuppressed()
EN

Stack Overflow用户
提问于 2015-07-29 03:37:57
回答 2查看 82关注 0票数 2

考虑下面的示例代码片段:

代码语言:javascript
复制
/**
 * @throws \DomainException
 */
public function doFoo()
{
    try {
        // Do a unit of work with in a transaction.
        // This code could throw a SomeOtherException.
        // In this case the transaction should be rolled back
        // and a \DomainException should be thrown.

    } catch (SomeOtherException $e1) {
        try {
            $this->pdo->rollback();
            throw new \DomainException("Failed", 0, $e1);

        } catch (\PDOException $e2) {
            // $e2 is lost!
            throw new \DomainException("Failed even more", 0, $e1);
        }
    }
}

不可变的约定只允许抛出DomainException。我对第二个catch块(内部catch (PDOException $e2))感兴趣。我可以使用$e1或$e2作为前一个异常,但不能同时使用两者。

我不喜欢一个异常被吞噬(在本例中是$e2)。那么,我如何抛出完整的错误信息,即包含$e1和$e2的\DomainException?我正在考虑将$e1添加到$e2的根目录中,并像以前一样使用$e2,但是PHP的Exception是不可变的。

编辑: PDO只是一个典型的用例。我也可以是对这两个异常的堆栈跟踪感兴趣的任何其他API。

Edit2:将其视为一个不能更改的接口的实现。

Edit3: Java的Throwable.addSupressed()非常适合这里。这可能有助于理解用例。

EN

回答 2

Stack Overflow用户

发布于 2015-07-29 03:48:46

您可能会这样做:

代码语言:javascript
复制
catch (\PDOException $e2) {
    // Probably you do even need to pass more parameters
    // to PDOException() to make it an exact "clone|brother". 
    // However, should get the concept out of it.
    $e = new \PDOException($e2->getMessage(), 0, $e1);
    throw $e;
}

不幸的是,在这种情况下,您将丢失$e2 ( PDOException)的堆栈跟踪。要解决此问题,您可以创建具有两个附加属性(如$domainException$rollbackException )的自定义异常。您可以简单地覆盖该类中的getMessage(),并组合嵌套异常的消息,以在日志文件中获得一致的错误消息。

顺便说一句,这是个好问题。我很好奇别人会怎么说。

票数 0
EN

Stack Overflow用户

发布于 2015-08-01 17:04:18

我发现finally确实是自动完成所有事情的:

代码语言:javascript
复制
try {
    throw new Exception("A");

} finally {
    throw new Exception("B");
}

这将打印以下内容:

Test.php致命错误:未捕获异常' exception‘,消息'A’位于/

/malkusch/tmp/test.php:4堆栈跟踪:

#0 {main}

/home/malkusch>/tmp/test.php:7堆栈跟踪中包含消息'B‘的下一个异常' exception’:

#0 {main}

我没有想到这是因为两个异常之间没有因果关系,但这是可以接受的,因为Exception::getPrevious()没有进一步的语义指定。

不幸的是,这是未记录的行为,不能被认为是稳定的。Bug #68270表明,目前还没有人知道预期的行为应该是什么。所以依赖它是不安全的。让我们看看discussion in internals会带来什么。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31685584

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档