对于我的Catalyst
项目,我使用自己的基于Moose
的异常类型,它与Catalyst
和我的命令行应用程序兼容。
为了向Catalyst REST接口的客户端提供错误消息,我实现了一个code
子例程,它提供了http状态代码作为我的异常类的一部分。这样,我想使用Plack::Middleware
的pod文档中描述的Plack::Middleware::HTTPExceptions
。
一切正常。异常以我希望返回的方式返回给客户端。
我的问题是:每当我抛出一个异常时,就会被中间件抓住,我的日志记录(Log::Log4perl
)就会丢失,我在Catalyst
'中找不到任何痕迹或错误。 s web服务器perl脚本输出。
每当我抛出错误时,我的异常类都没有封装,但是稀有字符串(如die "BOOM!"
),会写入日志输出并记录错误(显然,错误是由{{1}捕获的并且不会被重新抛出。)
如果必须将异常重新抛给中间件,我如何告诉Catalyst
保留日志记录请求?
答案 0 :(得分:0)
这个问题似乎有两个部分,但我认为这涵盖了它。这确实是设置Log4perl以记录错误的问题,但有Catalyst和Plack考虑因素。
首先,这将是我将拥有的典型log4perl配置设置:
log4perl.logger = DEBUG, FileAppndr, Screen, DebugPanel
log4perl.appender.FileAppndr = Log::Log4perl::Appender::File
log4perl.appender.FileAppndr.filename = log/server.log
log4perl.appender.FileAppndr.autoflush = 1
log4perl.appender.FileAppndr.stderr = 1
log4perl.appender.FileAppndr.layout = PatternLayout
log4perl.appender.FileAppndr.layout.ConversionPattern=%d [%p] - %m%n
log4perl.appender.Screen = Log::Log4perl::Appender::Screen
log4perl.appender.Screen.stderr = 1
log4perl.appender.Screen.autoflush = 1
log4perl.appender.Screen.layout = PatternLayout
log4perl.appender.Screen.layout.ConversionPattern=%d [%p] - %m%n
请注意stderr
值包含在1
中。因此,这告诉log4perl捕获stderr
以进行日志记录。
在Catalyst方面,我实际上有一些非常自定义的上下文初始化代码,但基本上设置了两件事情;
主要通过$c->log
加载PSGI中间件Plack::Middleware::Log4perl。我实际上在加载catalyst配置时通过psgi_middleware
配置键执行此操作。所以在配置行中没有比#34; Log4perl"因为一切都已经在" Plack :: Middleware"上下文路径。
第二部分将有#34;接送"加载的" log4perl"实例并分配给psgi.logger
,以便任何PSGI组件可以根据需要访问记录器。
那么,任何后来的陈述将会重新抛出"在这样的代码中:
my $e = HTTP::Exception->new(404);
$e->status_message("BOOM!!");
$e->throw;
实际上会在" log4perl"输出,以及任何原始die
语句。
至少在Catalyst 5.90060及更高版本上就是这种情况。关于HTTP :: Exception类型类,还有一些额外的细节需要添加。
答案 1 :(得分:0)
即使Neil的回答包含几个正确的陈述,我应用于我的Catalyst应用程序,但我没有得到任何输出。我通过子类Catalyst::Engine
来解决这个问题。此子类仅重新定义finalize_error
,并保持其余功能不变。在找到我自己的异常类型的情况下,我设置了一个单独的响应主体和状态代码,以通过重新抛出异常"梯形图来实现与我相同的结果"。