在 PHP 中重新抛出异常是否会破坏堆栈跟踪


Does re-throwing an exception in PHP destroy the stack trace?

在 C# 中,执行以下操作会破坏异常的堆栈跟踪:

try{
    throw new RuntimeException();
}
catch(Exception e){
    //Log error
    //Re-throw
    throw e;
}

因此,最好使用 throw 而不是throw e。这将允许相同的异常向上传播,而不是将其包装在新的异常中。

但是,在 PHP 中使用throw;而不指定异常对象是无效的语法。这个问题在 PHP 中根本不存在吗?按如下方式使用抛出$e不会破坏堆栈跟踪吗?

<?php
try{
    throw new RuntimeException();
}
catch(Exception $e){
    //Log error
    //Re-throw
    throw $e;
}

当你像以前一样在PHP中抛出$e时,你重新抛出现有的异常对象而不改变其内容的任何内容,并发送所有给定的信息,包括捕获的异常的堆栈跟踪 - 所以你的第二个例子是在PHP中重新抛出异常的正确方法。

如果(无论出于何种原因)你想抛出最后一条消息的新位置,你必须重新抛出一个新创建的异常对象:

throw new RuntimeException( $e->getMessage() );

请注意,这不仅会丢失堆栈跟踪,还会丢失除消息之外可能包含在异常对象中的所有其他信息(例如 CodeFileLine RuntimeException)。所以一般不建议这样做!

重新引发相同的异常不会破坏堆栈跟踪。但是根据你的需要,你可能只想抛出相同的异常或构建一个异常链接(参见 PHP 文档> Exception::__construct )

这个答案很好地解释了何时以及为什么会选择一种方法而不是另一种方法。

是的。这是捕获异常并重新抛出携带堆栈跟踪数据的同一异常对象的最佳方法。一旦你到达处理请求的方法点,只需在那里捕获它并相应地将响应发送回用户。

抛出一个新的异常对象是一个坏主意,它会丢失堆栈跟踪并创建一个导致内存负载的额外对象。

希望这有帮助。