Php, how to cast/convert Exception to RuntimeException?

huangapple go评论61阅读模式
英文:

Php, how to cast/convert Exception to RuntimeException?

问题

这是一个代码片段:

function test()
{
    if (mt_rand(1,4) === 2)
    {
        throw new \Exception('exception');
    }
}

try
{
    test();
}
catch(\Exception $e)
{
    //throw $e;
    throw new \RuntimeException($e->getMessage());
}

这只是一个简单的示例,但在两个项目中都使用了名为 test() 的函数。在其中一个项目中,它可能会引发异常并被处理。但在另一个项目中,我不能处理它,而是要让它发生,并且可以处理堆栈。

但如果我使用 throw new \RuntimeException($e->getMessage()); 的形式,我将无法获得真正的堆栈跟踪,无法知道它是否发生在 test() 函数中。

但如果我使用 throw $e; 的形式,它是一个 \Exception 而不是一个 RuntimeException

通常,异常是通常需要捕获的异常。但 RuntimeException 不应该被捕获,因为它可以在代码中解决。那么如何将该异常转换为 RuntimeException 呢?

英文:

there is a code snippet:

function test()
{
    if (mt_rand(1,4) === 2)
    {
        throw new \Exception('exception');
    }
}

try
{
    test();
}
catch(\Exception $e)
{
    //throw $e;
    throw new \RuntimeException($e->getMessage());
}

this is trivial example of course, but I there is a test() function which is used in two project. One of them it may throw an exception and is handled. But in another I must not handle it but let it happen and I can handle the stack.

But if I use the throw new \RuntimeException($e->getMessage()); form, I wont get the true stack trace, I wont know if that happened in test() function.

But if I use the throw $e; form, its an \Exception but not a RuntimeException.

Normally an Exception is a usual exception which must be caught. But RuntimeException must not be caught since it can be resolved in code. So how to make that exception to RuntimeException?

答案1

得分: 2

只返回翻译好的部分:

记住,RuntimeException 在其 构造函数 中有一个可用的 $previous 参数,您可以在其中提供原始异常:

try {
    test();
} catch (\Exception $e) {
    throw new \RuntimeException($e->getMessage(), $e->getCode(), $e);
}

如果您不需要它,也可以省略代码甚至消息:

throw new \RuntimeException($e->getMessage(), previous: $e);
throw new \RuntimeException(previous: $e);

堆栈跟踪可以从 .getTrace().getTraceAsString() 中检索,具体格式取决于所需格式,而先前的异常可以通过其 getter 获得,因此您可以获取整个历史记录:

try {
    // ....
} catch (\RuntimeException $e) {
    echo '捕获异常', PHP_EOL;
    while ($e) {
        echo '追踪 ', get_class($e), "\n";
        print_r($e->getTrace());
        $e = $e->getPrevious();
    }
}

演示

英文:

Remember that RuntimeException has a $previous argument available in its constructor where you can supply the original exception:

try {
    test();
} catch (\Exception $e) {
    throw new \RuntimeException($e->getMessage(), $e->getCode(), $e);
}

You can also omit the code, or even the message, should you not need it:

throw new \RuntimeException($e->getMessage(), previous: $e);
throw new \RuntimeException(previous: $e);

The stack trace can be retrieved from .getTrace() or .getTraceAsString(), depending on the format wanted, and previous exception is available through its getter, so you can get the whole history with:

try {
    // ....
} catch (\RuntimeException $e) {
    echo 'Exception caught', PHP_EOL;
    while ($e) {
        echo 'Trace for ', get_class($e), "\n";
        print_r($e->getTrace());
        $e = $e->getPrevious();
    }
}

Demo

huangapple
  • 本文由 发表于 2023年2月24日 01:36:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/75548376.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定