使用mod_cgi和amp;捕获错误的mod_perl

时间:2009-07-23 20:59:05

标签: perl error-handling mod-perl

提前感谢所有人。

我一直在做一些关于错误处理的研究,我不觉得我对我应该做的事情有了充分的了解。

序言:我的代码生活在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。)OO Exception Handling in Perl,但不是我想要的。我想要抓住的大多数东西都是死的。下一个链接还说这篇文章已过时并已弃用。

2。)Perl: $SIG{__DIE__}, eval { } and stack trace,但是我没有从中获得太多与我的目标相关的信息。

3。)实用模式Perl(O'Reilly),第21章“错误处理和调试”。值得庆幸的是,我所有的perl代码都使用了严格的警告,并且第6章“使用mod_perl编码编码”中提到的最重要的事情已经完成。

4。)我已经在“学习Perl”,“Perl Cookbook”,“Perl编程”和“高阶Perl”中挖掘了目录,并没有看到任何突出我的内容。如果你认为我错过了什么,请告诉我。 :)


我不记得在哪里(也许在“Practical mod_perl”中,但我读过你不应该把$ SIG {__ DIE __}弄乱。

2 个答案:

答案 0 :(得分:1)

您想要捕获哪种类型的错误? custom error pages不足以满足您的目的吗?

我的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
}

答案 1 :(得分:1)

您是否在Alternative Exception Handling Techniques上阅读了mod_perl网站的内容?它讨论了如何使用覆盖全局die()函数而不是使用$SIG{__DIE__}来捕获未捕获的异常。一种更清洁的方法,但并不完美。