line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package YATT::Lite::Partial::ErrorReporter; sub MY () {__PACKAGE__} |
2
|
|
|
|
|
|
|
# -*- coding: utf-8 -*- |
3
|
14
|
|
|
14
|
|
762
|
use strict; |
|
14
|
|
|
|
|
29
|
|
|
14
|
|
|
|
|
424
|
|
4
|
14
|
|
|
14
|
|
83
|
use warnings qw(FATAL all NONFATAL misc); |
|
14
|
|
|
|
|
26
|
|
|
14
|
|
|
|
|
635
|
|
5
|
|
|
|
|
|
|
use YATT::Lite::Partial |
6
|
14
|
|
|
|
|
82
|
(fields => [qw/cf_at_done |
7
|
|
|
|
|
|
|
cf_error_handler |
8
|
|
|
|
|
|
|
cf_die_in_error |
9
|
|
|
|
|
|
|
cf_ext_pattern |
10
|
14
|
|
|
14
|
|
7396
|
/]); |
|
14
|
|
|
|
|
33
|
|
11
|
|
|
|
|
|
|
require Devel::StackTrace; |
12
|
|
|
|
|
|
|
|
13
|
14
|
|
|
14
|
|
8504
|
use YATT::Lite::Error; |
|
14
|
|
|
|
|
35
|
|
|
14
|
|
|
|
|
683
|
|
14
|
14
|
|
|
14
|
|
78
|
use YATT::Lite::Util qw/incr_opt/; |
|
14
|
|
|
|
|
28
|
|
|
14
|
|
|
|
|
13780
|
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
#======================================== |
18
|
|
|
|
|
|
|
# error reporting. |
19
|
|
|
|
|
|
|
#======================================== |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
sub error { |
22
|
31
|
50
|
|
31
|
0
|
585
|
(my MY $self) = map {ref $_ ? $_ : MY} shift; |
|
31
|
|
|
|
|
115
|
|
23
|
31
|
|
|
|
|
123
|
$self->raise(error => incr_opt(depth => \@_), @_); |
24
|
|
|
|
|
|
|
} |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
sub error_with_status { |
27
|
0
|
0
|
|
0
|
0
|
0
|
(my MY $self) = map {ref $_ ? $_ : MY} shift; |
|
0
|
|
|
|
|
0
|
|
28
|
0
|
|
|
|
|
0
|
my ($code) = shift; |
29
|
0
|
|
|
|
|
0
|
my $opts = incr_opt(depth => \@_); |
30
|
0
|
|
|
|
|
0
|
$opts->{http_status_code} = $code; |
31
|
0
|
|
|
|
|
0
|
$self->raise(error => $opts, @_); |
32
|
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
sub make_error { |
35
|
31
|
|
|
31
|
0
|
68
|
my ($self, $depth, $opts) = splice @_, 0, 3; |
36
|
31
|
|
|
|
|
83
|
my ($fmt, @args) = @_; |
37
|
31
|
|
|
|
|
141
|
my ($pkg, $file, $line) = caller($depth); |
38
|
31
|
|
|
|
|
62
|
my $bt = do { |
39
|
31
|
|
|
|
|
85
|
my @bt_opts = (ignore_package => [__PACKAGE__]); |
40
|
31
|
50
|
|
|
|
95
|
if (my $frm = delete $opts->{ignore_frame}) { |
41
|
|
|
|
|
|
|
# $YATT::Lite::CON->logdump(ignore_frame => $frm); |
42
|
|
|
|
|
|
|
push @bt_opts, frame_filter => sub { |
43
|
0
|
|
|
0
|
|
0
|
my ($hash) = @_; |
44
|
0
|
|
|
|
|
0
|
my $caller = $hash->{'caller'}; |
45
|
0
|
|
0
|
|
|
0
|
my $all_match = grep {($frm->[$_] // '') eq ($caller->[$_] // '')} |
|
0
|
|
0
|
|
|
0
|
|
46
|
|
|
|
|
|
|
1, 2; # __FILE__, __LINE__ |
47
|
|
|
|
|
|
|
# print STDERR YATT::Lite::Util::terse_dump("filter: ", $all_match, $frm, $caller), "\n"; |
48
|
0
|
|
|
|
|
0
|
$all_match != 2; |
49
|
|
|
|
|
|
|
} |
50
|
0
|
|
|
|
|
0
|
} |
51
|
31
|
|
|
|
|
194
|
Devel::StackTrace->new(@bt_opts); |
52
|
|
|
|
|
|
|
}; |
53
|
|
|
|
|
|
|
|
54
|
31
|
|
33
|
|
|
21075
|
my $pattern = $self->{cf_ext_pattern} // qr/\.(yatt|ytmpl|ydo)$/; |
55
|
|
|
|
|
|
|
|
56
|
31
|
|
|
|
|
48
|
my @tmplinfo; |
57
|
31
|
|
|
|
|
123
|
foreach my $fr ($bt->frames) { |
58
|
443
|
50
|
|
|
|
23665
|
my $fn = $fr->filename |
59
|
|
|
|
|
|
|
or next; |
60
|
443
|
50
|
|
|
|
3235
|
$fn =~ $pattern |
61
|
|
|
|
|
|
|
or next; |
62
|
0
|
|
|
|
|
0
|
push @tmplinfo, tmpl_file => $fn, tmpl_line => $fr->line; |
63
|
0
|
|
|
|
|
0
|
last; |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
$self->Error->new |
67
|
31
|
100
|
100
|
|
|
514
|
(file => $opts->{file} // $file, line => $opts->{line} // $line |
|
|
50
|
100
|
|
|
|
|
68
|
|
|
|
|
|
|
, @tmplinfo |
69
|
|
|
|
|
|
|
, (@args |
70
|
|
|
|
|
|
|
? (format => $fmt, args => \@args) |
71
|
|
|
|
|
|
|
: (reason => $fmt)) |
72
|
|
|
|
|
|
|
, backtrace => $bt |
73
|
|
|
|
|
|
|
, $opts ? %$opts : ()); |
74
|
|
|
|
|
|
|
} |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
# $yatt->raise($errType => ?{opts}?, $errFmt, @fmtArgs) |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
sub raise { |
79
|
31
|
|
|
31
|
0
|
76
|
(my MY $self, my $type) = splice @_, 0, 2; |
80
|
31
|
50
|
33
|
|
|
225
|
my $opts = shift if @_ and ref $_[0] eq 'HASH'; |
81
|
|
|
|
|
|
|
# shift/splice しないのは、引数を stack trace に残したいから |
82
|
31
|
|
50
|
|
|
112
|
my $depth = (delete($opts->{depth}) // 0); |
83
|
31
|
|
|
|
|
118
|
my Error $err = $self->make_error(2 + $depth, $opts, @_); # 2==raise+make_error |
84
|
31
|
100
|
66
|
|
|
197
|
if (ref $self and my $sub = deref($self->{cf_error_handler})) { |
|
|
50
|
33
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
85
|
|
|
|
|
|
|
# $con を引数で引きずり回すのは大変なので、むしろ外から closure を渡そう、と。 |
86
|
|
|
|
|
|
|
# $SIG{__DIE__} を使わないのはなぜかって? それはユーザに開放しておきたいのよん。 |
87
|
2
|
50
|
|
|
|
7
|
unless (ref $sub eq 'CODE') { |
88
|
0
|
|
|
|
|
0
|
die "error_handler is not a CODE ref: $sub"; |
89
|
|
|
|
|
|
|
} |
90
|
2
|
|
|
|
|
6
|
$sub->($type, $err); |
91
|
|
|
|
|
|
|
} elsif ($sub = $self->can('error_handler')) { |
92
|
0
|
|
|
|
|
0
|
$sub->($self, $type, $err); |
93
|
|
|
|
|
|
|
} elsif (not ref $self or $self->{cf_die_in_error}) { |
94
|
0
|
|
|
|
|
0
|
die $err->message; |
95
|
|
|
|
|
|
|
} elsif ($err->{cf_http_status_code}) { |
96
|
|
|
|
|
|
|
# If http_status_code is specified explicitly (from error_with_status), |
97
|
|
|
|
|
|
|
# raise it immediately, with simple reason. (not full backtrace message). |
98
|
|
|
|
|
|
|
$self->raise_psgi_html($err->{cf_http_status_code} |
99
|
0
|
|
|
|
|
0
|
, $err->reason); |
100
|
|
|
|
|
|
|
} else { |
101
|
|
|
|
|
|
|
# 即座に die しないモードは、デバッガから error 呼び出し箇所に step して戻れるようにするため。 |
102
|
|
|
|
|
|
|
# ... でも、受け側を do {my $err = $con->error; die $err} にでもしなきゃダメかも? |
103
|
29
|
|
|
|
|
1062
|
return $err; |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
# XXX: 将来、拡張されるかも。 |
108
|
|
|
|
|
|
|
sub DONE { |
109
|
0
|
|
|
0
|
0
|
0
|
my MY $self = shift; |
110
|
0
|
0
|
|
|
|
0
|
if (my $sub = $self->{cf_at_done}) { |
111
|
0
|
|
|
|
|
0
|
$sub->(@_); |
112
|
|
|
|
|
|
|
} else { |
113
|
0
|
|
|
|
|
0
|
die \ 'DONE'; |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
sub raise_psgi_html { |
118
|
0
|
|
|
0
|
0
|
0
|
(my MY $self, my ($status, $html, @rest)) = @_; |
119
|
0
|
|
|
|
|
0
|
die [$status, ["Content-type" => "text/html; charset=utf-8", @rest] |
120
|
|
|
|
|
|
|
, [$html]]; |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
sub deref { |
124
|
31
|
100
|
|
31
|
0
|
400
|
return undef unless defined $_[0]; |
125
|
2
|
50
|
33
|
|
|
15
|
if (ref $_[0] eq 'REF' or ref $_[0] eq 'SCALAR') { |
126
|
0
|
|
|
|
|
0
|
${$_[0]}; |
|
0
|
|
|
|
|
0
|
|
127
|
|
|
|
|
|
|
} else { |
128
|
2
|
|
|
|
|
9
|
$_[0]; |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
1; |