标签/Tag为[eval]的文章

Perl eval 和 $SIG{__DIE__} ,

一般来说, Pel 中的 eval 可以捕获异常。 至少我是这样用的: 用来尝试运行一些操作,要是出错了也不会退出。 比如我经常用 Image::Info 来判断一个图像文件是否真的是图像,但是服务器上是否有 Image::Info是个问题。 简单概念代码如下:

code eval("use Image::Info qw(image_info);");
if ($@ eq "")
{
my $info = image_info("$tmpfilename");
if ($info->{error} eq "Unrecognized file format"){
$esB::base->error("该文件不是合法的图片文件。");
}
}

由于 eval 的存在, 如果系统没有 Image::Info ,那么简单的跳过判断,并不影响程序的继续执行。。

直到有一天, 我决定用 $SIG{__DIE__} 来自定义程序的的出错信息。 一样,概念代码如下

code $SIG{__DIE__} = \&esb_die;
sub esb_die {
my $error = shift;
$error =~ s!$ENV{'DOCUMENT_ROOT'}!/{you_root_dir}/!i;
my ($msg, $path) = split " at ",$error;
print "Content-type: text/html\n\n";
print qq~
<html>
<head><title>Easun CGI Error</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" >
</head>
<body >
<font size='6' color='#333366'>Easun CGI Error</font>
<hr size='1' color='#000000' noshade>
<font size='3' color='#00000'>
很抱歉,程式因为以下错误而异常退出:
<br><br><b>$msg</b><br><br>错误大概发生在: <font color='#000099'>$path</font><br><br>
<font size='3' color='#990000'><b>请注意,为了保证您的安全,您的程序的真实路径已经被程式自动过滤。</b></font>
</font>
</body></html> ~;
exit();
}

该操作也达到预期目的。

但是,当这两者同时运行时,$SIG{__DIE__} 居然捕获到了 eval 内的 $@ 。当系统没有找到Image::Info 时候,程序不再默默跳过继续执行。而是直接跳出到自定义错误页面。
信息如下

很抱歉,程式因为以下错误而异常退出: Can't locate Image/Info.pm in @INC (you may need to install the Image::Info module) (@INC contains: ./config ./ShareLib ./ D:/usr/site/lib D:/usr/lib .) 错误大概发生在: (eval 10) line 1.

如何协调这两者,是个问题。。。

记录下来,作为备忘。

--EOF--