1

I use Log4perl in one of my applications and created my own appender which inherits from Log::Dispatch::Email because I need some special handling of sendmail. This appender worked for some years now, but today I recognized some weird behavior in which $@ doesn't get set as before if I configure Log4perl to use my appender or simply Log::Dispatch::Email itself. I used to catch errors in the following way:

eval { main(); 1; };
if (my $error = $@)
{
  log()->error($error);
  exit(error_no_success());
}
exit(error_success());

If I remove the mail appender from my Log4perl configuration and my application dies in main, $error gets the message and it gets logged within the alternative. The problem now is that when I configure my own descendant of Log::Dispatch::Email or this abstract base class directly, $@ in the above statement is the empty string, resulting in the same error as before isn't recognized anymore. If I write something like eval {} or ... $@ is properly available and can be saved. The following works:

my $error = undef;
eval { main(); 1; } or $error = $@;
my $error2 = $@;
if ($error)
{
  log()->error($error);
  exit(error_no_success());
}
exit(error_success());

$error2 is always the empty string if I configure Log::Dispatch::Email in any way. Of course I don't want to change all my code which uses the first example and used to work before to the second one.

Is there anything wrong with my first example? From my point of view it looks like documented for eval in perldoc and it works without email appenders.

Can you think of any reason why using mail appenders changes the behavior on how or when or whatever Perl sets $@ in my second example? Any workarounds? I already had a look at the sources of Log::Dispatch but couldn't find anything obviously interfering with my code.

Thanks for any hints!

4

1 回答 1

0

PerlMonks的一些帮助下,我终于发现了问题: $@ 不可靠。我之前已经遇到过类似的问题,并且按照惯例在我的所有析构函数中本地化了 $@,显然我错过了一个,它用于记录一些调试输出。在任何日志语句之前在此析构函数中本地化 $@ 之后,我的问题也得到了解决,并且错误捕获再次起作用。我不知道为什么这个问题只使用 Log::Dispatch 触发,因为析构函数之前总是记录调试语句,但是无论如何......就像 PerlMonks 上的建议一样,将来应该切换到使用 Devel::EvalError。

于 2013-08-12T17:29:12.867 回答