|  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;  |