Validad::Tools::Plack::Middleware::Error
file: code/Validad::Tools::Plack::Middleware::Error
1: package Validad::Tools::Plack::Middleware::Error;
2:
3: use 5.018;
4: use strict;
5: use warnings;
6: use parent qw(Plack::Middleware);
7: use Plack::Util;
8: use Plack::Util::Accessor qw(error_root);
9: use Plack::Response;
10: use JSON::XS qw(encode_json);
11: use HTTP::Status qw(is_error);
12: use Scalar::Util 'blessed';
13: use Log::Any qw($log);
14:
15: my %cache;
16:
17: sub call {
18: my ( $self, $env ) = @_;
19: my $r;
20: eval { $r = $self->app->($env) };
21: my $error;
22: my $status = 500;
23: if ( my $e = $@ ) {
24: if ( blessed($e) ) {
25: if ( $e->can('message') ) {
26: $error = $e->message;
27: }
28: else {
29: $error = '' . $e;
30: }
31: $status = $e->http_status if $e->can('http_status') && $e->http_status;
32:
33: # HTTP::Throwable:
34: $status = $e->status_code if $e->can('status_code');
35: }
36: else {
37: $error = $e;
38: }
39: }
40: elsif ( is_error( $r->[0] ) ) {
41: my $raw = $r->[2];
42: $error = ref($raw) eq 'ARRAY' ? join( '', @$raw ) : $raw;
43: $status = $r->[0];
44: }
45: else {
46: return $r;
47: }
48:
49: my $req = Plack::Request->new($env);
50:
51: $log->error( $req->uri->as_string . ': ' . $error );
52: my $res = Plack::Response->new($status);
53: if (
54: ( exists $env->{HTTP_X_REQUESTED_WITH}
55: && $env->{HTTP_X_REQUESTED_WITH} eq 'XMLHttpRequest'
56: )
57: || ( exists $env->{HTTP_ACCEPT}
58: && $env->{HTTP_ACCEPT} =~ m{application/json}i )
59: ) {
60: $res->content_type('application/json');
61: $res->body(
62: encode_json( { status => 'error', message => "" . $error } ) );
63: }
64: else {
65: $res->content_type('text/html');
66: my $content = $self->rendered_error_page( $status, $error );
67: $res->body($content);
68: }
69: return $res->finalize;
70: }
71:
72: 1;