gpt4 book ai didi

perl - 为什么 DBI 的 RaiseError 不总是触发我的 CORE::GLOBAL::die 子例程?

转载 作者:行者123 更新时间:2023-12-01 05:38:37 25 4
gpt4 key购买 nike

我按照 brian d foy 的 article on the subject 中的描述覆盖了 CORE::GLOBAL::die :

BEGIN {
*CORE::GLOBAL::die = sub {
say "In CORE::GLOBAL::die: [@_]";
CORE::die(@_) if $^S;
exit 1;
}
}

最终目标是将 fatal error 写入日志,但目前已经足够了。让我们创建一个打开了 RaiseError 的数据库句柄,然后做一些事情来触发错误:

use DBI;

# Wrong password
my $dbh = DBI->connect(..., { PrintError => 0, RaiseError => 1 });

输出:

In CORE::GLOBAL::die: [DBI connect(...) failed: Access denied for user ...

到目前为止一切顺利。让我们用一些糟糕的 SQL 代替:

use DBI;

my $dbh = DBI->connect(..., { PrintError => 0, RaiseError => 1 });
my $sth = $dbh->prepare('SLECT 1');
$sth->execute;

输出:

DBD::mysql::st execute failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SLECT 1' at line 1 at ...

嗯,不是我所期望的(没有 In CORE::GLOBAL::die 消息)。根据docs ,当 RaiseError 开启时,

any method which results in an error will cause the DBI to effectively do a die("$class $method failed: $DBI::errstr")

我猜关键字是有效,因为我希望对die 的实际调用会调用我的CORE::GLOBAL::die.

我可以通过设置 HandleError 强制所有错误die:

my $dbh = DBI->connect(..., { HandleError => sub { die shift; } })

但由于 RaiseError“可用于强制错误引发异常,而不是简单地以正常方式返回错误代码”,我不明白为什么这是必要的。为什么设置 RaiseError 不会总是导致调用 CORE::GLOBAL::die 出错?这不是使用它的全部意义吗?

最佳答案

die 是一个 Perl 操作码(不是子例程)。它不能简单地被调用。部分 DBI 和 DBD 模块是用 C 语言编写的,因此它们将无法使用 die(如您的解决方法中那样不回调 Perl 代码)。

不过,您仍然可以 Hook $SIG{__DIE__}。正如文章所说,GLOBAL::CORE::die 适用于“您确实需要捕获对 die 的调用”(而不是捕获抛出的异常)。

关于perl - 为什么 DBI 的 RaiseError 不总是触发我的 CORE::GLOBAL::die 子例程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21170416/

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