gpt4 book ai didi

perl - 如何为模具处理程序提供更多上下文?

转载 作者:行者123 更新时间:2023-12-05 00:10:02 25 4
gpt4 key购买 nike

如果某些功能必须 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 访问它吗? ?或者我可以事先向处理程序提供一些数据吗?

我现在看到的两个选项:
  • 通过一些全局变量,我总是预先填充所需的数据,以防出现错误
  • 使用对象,其中包含 die_handler-method

  • 更好的方法来做到这一点?

    最佳答案

    我不确定你想要什么“上下文”,但是 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死了,具有完整的堆栈回溯,但在您的示例中 dieeval 捕获.死于 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 .

    如果您希望能够在钩子(Hook)中完全处理异常,请参阅 Devel::StackTrace
    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/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com