【问题标题】:How to handle errors in plack delayed response如何处理 plack 延迟响应中的错误
【发布时间】:2019-07-05 14:14:16
【问题描述】:

尝试处理延迟响应中的错误。

每次我发送 [200, [ 'Content-Type', 'application/json' ] 并在刷新其他类似的东西之前出错

$w->write("MyData");

$w->close();

我在 stdout 中收到警告,在 stderr 中收到错误,但页面仍在加载。

它将一直加载,直到我停止应用程序或手动停止页面加载。

如何停止在代码中加载页面或如何正确处理我使用延迟响应的此类应用程序中的错误?

Perl 版本 5.24 海带版本 1.02 与 Corona 一起运行 Plack。

我们正在处理抛出 Exception::Class 的错误。 使用 Try::Tiny 捕获错误。

还尝试了 eval 和其他东西,但它不起作用。 但是更改了 Try::Tiny -> TryCatc 并在出现任何错误时返回,但是 我需要为每个 catch 块写返回,它看起来很糟糕

#!/usr/bin/perl
use strict;
use warnings;

use Kelp::Less;
get '/hello' => sub  {
    return sub {
        my $res = shift;
        my $w = $res->([200, [ 'Content-Type', 'application/json' ]]);
        my $data = 10 / 0;
        $w->write("MyData");
        $w->close();
    }
};
run;

我正在寻找正确的错误处理, 我需要 try{} catch{};在每个可能失败的代码上?

感谢@ikegami 的回答,但在尝试使用 Object::Destoyer 和 Sub::ScopeFinalizer 后页面仍在加载。据我了解 $w(writer) 不会导致页面加载。退出作用域后,$w 来到 undef 然后没有什么可以关闭的,这里是代码。

#!/usr/bin/perl
use strict;
use warnings;

use Object::Destroyer;
use Kelp::Less;
get '/hello' => sub  {
    return sub {
        my $res = shift;

        my $w = $res->([200, [ 'Content-Type', 'application/json' ]]);
        my $g = Object::Destroyer->new( sub { $w->close if $w } );
        my $zzz = 1 / 0;
        $w->write("DATA");
        $w->close();
    }
};
run;

所以我想出了那个解决方案,你觉得呢?

#!/usr/bin/perl
use strict;
use warnings;

use Try::Tiny;
use Object::Destroyer;
use Kelp::Less;
get '/hello' => sub  {
    return sub {
        my $res = shift;

        my $w = $res->([200, [ 'Content-Type', 'application/json' ]]);
        my $g = Object::Destroyer->new( sub { $w->close if $w; } );
        my $ans = try {                                                                   
            my $zzz = 1 / 0;                                                              
        }                                                                                 
        catch {
            print $_;                                                                   
            return;                                                                       
        };                                                                                
        return unless $ans;

        $w->write("DATA");
        $w->close();
    }
};
run;

【问题讨论】:

  • Try::Tiny 只使用 eval,所以你声称它不适用于 eval 并且它确实适用于 Try::Tiny 是不一致的
  • 下面的怎么样:use Sub::ScopeFinalizer qw( scope_finalize ); my $w; my $guard = scope_finalize { $w->close if $w }; $w = $res->(...); ...;
  • 或者更简单但更神奇的:use Object::Destroyer; my $w = Object::Destroyer->new( $res->(...), 'close' ); ...;
  • 对不起,我周末很忙。我试过了,但他们都没有帮助。 Sub::ScopeFinalizer 返回:{` Can't call method "scope_finalizer" on an undefined value at } Object::Destroyer 返回 { Object::Destroyer 要求 Plack::Util::Prototype 有一个关闭方法 `}
  • 大声笑,无法与代码格式相处。 5分钟后无法编辑。 { Sub::ScopeFinalizer returns: Can't call method "scope_finalizer" on an undefined value at ...} Object::Destroyer returns Object::Destroyer requires that Plack::Util::Prototype has a close method }

标签: perl plack


【解决方案1】:

通过包装应用解决这个问题

Plack::Middleware::HTTPExceptions

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多