捕获Perl中的运行时错误并转换为异常

时间:2013-10-29 20:56:53

标签: perl runtime-error

Perl目前以这样的方式实现$SIG{__DIE__},它将捕获发生的任何错误,即使在eval块内也是如此。这有一个非常有用的属性,您可以在发生错误的确切位置暂停代码,收集实际错误的堆栈跟踪,将其包装在对象中,然后使用此对象作为参数手动调用die。 / p>

不推荐滥用$SIG{__DIE__}。正式地说,您应该用$SIG{__DIE__}替换*CORE::GLOBAL::die。但是,这两个 NOT 远程等效。发生运行时错误时,*CORE::GLOBAL::die NOT 被调用!它只是替换对die()的显式调用。

我对替换骰子不感兴趣。

我特别感兴趣的是捕捉运行时错误。

我需要确保在任何模块中任何深度的任何函数中的任何运行时错误都会导致Perl将控制传递给我,以便我可以收集堆栈跟踪并重新抛出。这需要在eval块内部工作 - 一个或多个封闭的eval块可能想要捕获异常,但运行时错误可能是在任何模块内部没有封闭eval的函数中。

$SIG{__DIE__}完全支持这一点 - 并忠实地为我服务了几年或更长时间 - 但Be™警告说,这个奇妙的设施可能随时被抢走,我不想要一天下来令人讨厌的惊喜。

理想情况下,对于Perl本身,他们可以为此目的创建一个新信号$SIG{__RTMERR__}(无论如何,切换信号很容易,因为它只挂在一个地方)。不幸的是,我的说服力不会导致酗酒者破解瓶子,所以假设这不会发生,那么究竟应该如何才能实现干净地捕捉运行时错误的目标呢?

(例如,另一个答案在这里推荐Carp :: Always,其中......也挂钩DIE!)

1 个答案:

答案 0 :(得分:3)

做吧。我做到了可能每个知道这个钩子的人都已经做到了。

它是 Perl ;它可以追溯到几十年前。我在这里解释“弃用”是指“如果你不需要它,请不要使用它,ew,粗略”。但你确实需要它,并且似乎理解其含义,所以我们去了。我非常怀疑一个不可替代的语言功能很快就会消失。

然后在CPAN上发布您的工作,以便下一个开发者不需要再次重新发明它。 :)