2

提前感谢大家。

我一直在做一些关于错误处理的研究,但我觉得我对我应该做什么没有深入的了解。

前言:我的代码在 Apache 中并在浏览器中执行,我的目标不包括命令行执行。

我希望 CGI::Carp (fatalsToBrowser) 的行为能够捕获输出并能够将其扔到我自己的模板页面中,通过电子邮件发送等...我确实注意到 fatalsToBrowser 不起作用与 mod_perl。有谁知道为什么?Apache/mod_perl 是如何阻碍的?


第一个目标:如果代码是用 mod_perl 或 mod_cgi 执行的,我想把一些东西放在一起。

第二个目标:我想要一个高级方法来捕获类似于 .NET 的 Application_Error (在 global.asax 中)和 PHP 的 set_exception_handler() 和 set_error_handler() 方法的所有错误。这些允许您在引发错误时进行控制,而无需将代码包装在凌乱的/gross try-catch 语句中。


我读过/评论过的东西:

1.) Perl 中的 OO 异常处理,但不是我想要的。我想抓住的大部分东西都是死()。下一个链接还说这篇文章已过时且已弃用。

2.) Perl: $SIG{__DIE__}, eval { } 和 stack trace,但我并没有从中得到太多与我的目标相关的东西。

3.) 实用模式 Perl (O'Reilly),第 21 章“错误处理和调试”。谢天谢地,我所有的 perl 代码都使用了 strict 并启用了警告,并且第 6 章“使用 mod_perl 进行编码”中提到的最重要的事情已经完成。

4.) 我翻阅了“Learning Perl”、“Perl Cookbook”、“Programming Perl”和“Higher Order Perl”中的目录,并没有发现任何让我印象深刻的东西。如果你认为我错过了什么,请告诉我。:)


我不记得在哪里(也许在“实用 mod_perl”中,但我读过你不应该与 $SIG{__DIE__}.

4

2 回答 2

1

你想捕捉什么类型的错误?自定义错误页面是否不足以满足您的目的?

我的 CGI 脚本很短(好吧,这真的很简单——而且未经测试):

#!/usr/bin/perl

use strict;
use warnings;

use My::App;
use My::ErrorReporter qw( error_to_html );

run();

sub run {
    my $app = eval {
        My::App->new(
            'some_param',
            'another_param',
        )
    };

    unless ( $app ) {
        print error_to_html( $@ );
        return;
    }

    eval {
        $app->handle_request;        
    } and return;

    print error_to_html( $@ );
    return;
}

__END__

现在,fatalsToBrowser不适合您的用户。那是对你的发展援助。用户看到的错误消息不应传达有关程序的信息。因此,例如,在打开和读取配置文件的例程中,您应该执行以下操作:

sub read_my_config {
    my $self = shift;

    open my $config_h, '<', $self->config_file;

    unless ( $config_h ) {
        # This goes to the Apache error log where you can read it
        warn sprintf(
            "Cannot open '%s': %s", 
            $self->config_file, $!
        );
        # This is for web site visitors to see
        die "Cannot open configuration file";
    }

    # rest of the code
}
于 2009-07-23T21:29:58.787 回答
1

您是否阅读过mod_perl网站上关于替代异常处理技术的文章?它讨论了如何通过使用覆盖全局die()函数而不是使用$SIG{__DIE__}. 一种更清洁的方法,但并不完美。

于 2009-07-24T00:13:11.207 回答