标簽/Tag為[sig]的文章

Perl eval 和 $SIG{__DIE__} ,

一般來說, Pel 中的 eval 可以捕獲異常。 至少我是這樣用的: 用來嘗試運行一些操作,要是出錯了也不會退出。 比如我經常用 Image::Info 來判斷一個圖像文件是否真的是圖像,但是服務器上是否有 Image::Info是個問題。 簡單概念代碼如下:

code eval("use Image::Info qw(image_info);");
if ([email protected] 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 内的 [email protected] 。當系統沒有找到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--