这是Apache 2.2上的mod_perl2,Win32的activestate perl 5.10。
我超越
$SIG{__DIE__}
并打开DBI的raiseError标志,该标志远离文档,当数据库调用失败时应调用我的override。几乎总是这样,除了一种情况,我不明白为什么。
我的剧本有一个
our $page
变量,作为mod euperl2,我可以从重写中得到这个,比如:
use Carp::Trace;
my $full_trace = Carp::Trace::trace;
$full_trace =~ m/^(ModPerl::ROOT::ModPerl::Registry::.*::)handler .*$/m;
my $page;
if (defined $1)
{
eval '$page = $' . $1 . 'page';
if (defined $page)
{
$json = 1 if defined $$page{json_response};
if (defined $$page{dbh})
{
my $errno = $$page{dbh}->state;
if ($errno ~~ $$page{error_handling}{allowed})
{
# allowed to let it go--no report, expected possible user error at some level that couldn't be caught sooner (usually db level)
my $errmsg = $$page{error_handling}{translation_map}{$errno};
if (defined $errmsg)
{
...
这个很好用。现在,在那里面
$page
,我有一个数组引用“allowed”错误值,当它们从数据库返回时,我想对它们做一些不同的事情。当数据库抛出其中一个错误时,我想将其转换为用户友好的消息,
$r->print
在JSON中,停止执行(行为A)。出于某种原因,它将控制权返回到脚本(行为B)。
我的剧本的主要部分是:
{
$$page{error_handling}{allowed} = ['22007'];
$$page{json_response}{result} = $page->one_liner("select 'aa'::timestamp");
$$page{json_response}{test} = $$page{error_handling}{state};
}
$page->make_json; # just JSONifies $$page{json_response} and prints it
如果我对第一行进行注释,我会得到一个正常的错误(处理一些意外的事情)(行为C),这是我所期望的,因为我没有将发生的错误添加到允许的错误列表中。真正奇怪的是,如果我把第一行剪下来贴到我的
$sig_
重写,它工作:JSON响应在重写、打印和执行之前停止
{test}
分配(行为A)。还是个陌生人,我可以
{allowed}
对于任何一组数字,只要它特别包含“22007”,我就得到行为B。如果它不包含行为C,则得到行为C。更奇怪的是,我实际上可以用任何内容(警告、调用
CORE::die
等等,只要它编译,我仍然得到行为b——即使覆盖不再包含任何使其成为可能的代码!另外,我也没有收到
warn
和
核心:模具
,只是在日志中保持沉默,所以我甚至无法尝试通过重写手动跟踪执行路径。
在每次脚本保存之间,我都重新启动了Apache2.2。我甚至将重写移到了脚本本身所在的同一个脚本文件中,从它通常所在的模块中移出,并注释掉了重写通常所在的整个模块文件,然后重新启动。
如果我去掉第一行,或者去掉22007行,我可以
警告
和
die
另外,手动调试我喜欢的一切,一切都按预期工作。“22007”的特点是,尽管服务器重置,但它始终不会输出任何不同的内容?在整个项目中的任何其他地方都没有对“22007”的引用,除了翻译映射,我可以完全从该文件中删除它并重新启动,结果也没有什么不同。它的行为就好像它从当天早些时候缓存了我的覆盖,并且永远不会忘记。这也不是浏览器缓存的问题,因为我可以添加随机查询字符串,结果也没有什么不同。
这是我所经历过的最奇怪和最令人沮丧的mod perl2体验,我已经没有想法了。有人有什么提示吗?我唯一能想到的是,这是一个缓存问题,但我已经多次重新启动了该服务。
因为这是一天的结束,我想我会尝试完全重新启动服务器计算机,它仍然没有改变任何东西。在重新启动服务器之前,我甚至更改了
{state}
分配给此:
$$page{error_handling}{state} = 'my face'; # $errno;
然而,后来的产出
{测试}
作为“22007”,只有我离开了才应该是这样
= $errno
完整的。
即使它是,比方说,通过反向代理来进行缓存,这种情况对我来说也没有意义,因为请求可能不同。在完全重新启动服务器之后,它如何仍然分配代码中不再存在的值,即它如何使用我的旧值
$sig { ydi-diee}}
完全重新启动后,当它不再存在于任何文件中时是否重写?
更新:
我还尝试将允许的错误更改为“42601”,并将DB调用更改为
'select'
,它生成错误代码,但没有将其添加到翻译映射中。它仍然给我行为B,设置
{状态}
到“42601”,所以它不特定于“22007”。输入的任何错误代码
{允许}
,如果实际发生该错误,则运行的是旧版本的重写。导致一个不在
{允许}
它运行当前版本。但它如何知道当前的错误是否在
{允许}
或者这意味着什么,在进入超控之前?(因为覆盖是唯一
允许
对当前错误进行了灰映射。)