- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如果某些功能必须 die
,我希望在错误消息中有更多上下文.在某些情况下我可以提供它,在其他情况下我找不到好方法。例如,使用 RaiseError
与 Postgres 相关的选项我在每次失败时都会遇到异常,但我无法为这些错误提供更多上下文。我尝试使用 die
-handler,但我无法找到一种理智的方式来包含被调用子程序的参数,至少:
try {
x( 'y' );
} catch {
say "CATCHED error: $_";
};
sub _die_handler {
my @caller = caller(1);
say "@caller"; # how to access @_ for this frame
die @_;
}
sub x {
local $SIG{__DIE__} = \&_die_handler;
die;
}
x
以“y”作为参数调用?
@_
在我的子程序中,我可以从我的
_die_handler
访问它吗? ?或者我可以事先向处理程序提供一些数据吗?
最佳答案
我不确定你想要什么“上下文”,但是 Carp是我们这里的 friend 。
一方面,包括 use Carp::Always;
我们会在所有错误上打印完整的堆栈回溯。
如果您更愿意选择,最简单的方法是直接使用合适的Carp
常规
use warnings;
use strict;
use feature 'say';
use Carp;
eval { my $y = 10; x($y) };
if ($@) {
print "eval: $@";
# print/log else as wanted, recover and proceed or exit
}
say "done";
sub x {
local $SIG{__DIE__} = \&Carp::confess;
# ...
my $bad_math = $_[0] / 0;
}
Carp::confess
死了,具有完整的堆栈回溯,但在您的示例中
die
被
eval
捕获.死于
confess
并捕获异常,您会从
confess
获得“调用上下文”但也可以在
eval
中保留控制权以按照您的意愿继续进行。 “捕获。”
eval: Illegal division by zero at error_context.pl line 18. at error_context.pl line 18. main::x(10) called at error_context.pl line 7 eval {...} called at error_context.pl line 7done
Without eval
the program would terminate (unless there's an eval
further up the stack) but we'd still get the full backtrace of the call. There are routines in Carp
which don't die, and among them cluck
also prints backtrace.
For a more custom handling use the $SIG{__DIE__}
hook. A little snag with Carp
is that the routine with backtrace which doesn't die, cluck
, just prints to STDERR
stream; we can't easily get that message to build it up further. The trace used to be in longmess
but is not anymore and I don't think that one can get the stacktrace from Carp
without die
-ing.
Then use confess
, which returns the trace, and wrap the call with eval
sub _die_handler {
my $other_info = '...';
Carp::confess($other_info . "\n" . $_[0]);
}
...
sub x {
local $SIG{__DIE__} = \&_die_handler;
...
}
...
eval { x() };
if ($@) { ... } #--> confess's trace with $other_info prepended
die
整个消息然后在
$@
在您的
eval
.为此,您仍然需要
eval
.
use Devel::StackTrace;
sub _die_handler {
my $trace = Devel::StackTrace->new;
# Add other info to `$trace` object, or build error object/structure
# Print/log/etc $trace (or your new error structure/object), or
#die $trace;
}
Devel::StackTrace
如果你想重新抛出当然也很有用,在这种情况下你可以将它的对象传递给
die
.请参阅文档,特别是构造函数选项。
$SIG{__DIE__}
;这可能很棘手。我想说,最好使用
Carp
.
caller
手动遍历堆栈。并通过
PadWalker
从每一帧中检索词汇.
this post 中的一个示例.
关于perl - 如何为模具处理程序提供更多上下文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58906167/
我是一名优秀的程序员,十分优秀!