File Coverage

blib/lib/Cake/Exception.pm
Criterion Covered Total %
statement 54 91 59.3
branch 12 30 40.0
condition 4 6 66.6
subroutine 10 14 71.4
pod 0 8 0.0
total 80 149 53.6


line stmt bran cond sub pod time code
1             package Cake::Exception;
2 8     8   44 use strict;
  8         14  
  8         269  
3 8     8   44 use Carp;
  8         10  
  8         458  
4 8     8   38 use Data::Dumper;
  8         11  
  8         438  
5            
6             our @CARP_NOT;
7 8     8   40 use base 'Exporter';
  8         12  
  8         823  
8             our @EXPORT = qw(
9             error
10             log
11             warn
12             );
13            
14             ##For quick testing
15             BEGIN {
16 8     8   9918 $SIG{__DIE__} = \&trapper;
17             }
18            
19             sub trapper {
20 22     22 0 116325 my $message = shift;
21 22         146 $message = __PACKAGE__->backtrace($message);
22 22         9311 print STDOUT <
23             Content-Type: text/html
24             $message
25             END
26             }
27            
28             ## die nicely just to detach the flow sequence of Cake action
29             ## and not a real die
30             my $kill_nicely = 0;
31             sub Mercy_Killing {
32 0     0 0 0 my $c = shift;
33 0         0 $kill_nicely = 1;
34 0         0 die();
35             }
36            
37             sub error {
38 0     0 0 0 my ($self,$error) = @_;
39 0         0 local @CARP_NOT = qw(Cake);
40 0 0       0 if ($kill_nicely){
41 0         0 $kill_nicely = 0;
42 0         0 return;
43             }
44            
45 0         0 my ($message,$caller);
46 0 0       0 if (ref $error eq 'HASH'){
47 0         0 $message = $error->{message};
48 0         0 $caller = $error->{caller};
49 0         0 $error = $message.' at '.$caller->[1].' line '.$caller->[2];
50             }
51            
52 0 0       0 if ($self->debug){
53 0 0       0 $error = __PACKAGE__->backtrace($error) if $error;
54 0         0 local $SIG{__DIE__} = \&handleErrors($self,$error);
55             } else {
56 0 0       0 if ($self->app->can('errors')){
57 0         0 $self->app->errors($self,$error);
58             } else {
59 0         0 $self->status_code('404');
60 0         0 $self->body('something wrong is going on');
61             }
62             }
63 0         0 return 1;
64             }
65            
66             sub log {
67 18     18 0 26 my $self = shift;
68 18 50       42 if (@_ > 1){
69 0         0 push @{$self->app->{log}},\@_;
  0         0  
70             } else {
71 18         19 push @{$self->app->{log}},shift;
  18         75  
72             }
73 18         38 return 1;
74             }
75            
76             sub warn {
77 0     0 0 0 my $self = shift;
78 0         0 my $message = shift;
79 0         0 my ($caller,$file,$line) = caller;
80 0 0       0 $self->app->{warnings}->{$caller} = [] if !$self->app->{warnings}->{$caller};
81 0         0 push @{ $self->app->{warnings}->{$caller} }, {
  0         0  
82             line => $line,
83             message => $message
84             };
85 0         0 return 1;
86             }
87            
88             sub handleErrors {
89 0     0 0 0 my $self = shift;
90 0         0 my $message = shift;
91 0         0 $self->status_code(500);
92 0         0 $self->body($message);
93 0         0 return $self;
94             }
95            
96             ########proudly stolen from Dancer :P
97             sub backtrace {
98 22     22 0 51 my ($self,$message) = @_;
99 22         304 $message =
100             qq|
| . _html_encode($message) . "
";
101            
102             # the default perl warning/error pattern
103 22         176 my ($file, $line) = ($message =~ /at (\S+) line (\d+)/);
104            
105             # the Devel::SimpleTrace pattern
106 22 100 66     302 ($file, $line) = ($message =~ /at.*\((\S+):(\d+)\)/)
107             unless $file and $line;
108            
109             # no file/line found, cannot open a file for context
110 22 100 66     112 return $message unless ($file and $line);
111            
112             # file and line are located, let's read the source Luke!
113            
114 6 50       311 open FILE, "<$file" or return $message;
115 6         459 my @lines = ;
116 6         85 close FILE;
117            
118 6         11 my $backtrace = $message;
119            
120 6         27 $backtrace
121             .= qq|
| . "$file around line $line" . "
";
122            
123 6         11 $backtrace .= qq|
|;
 
124            
125 6         16 $line--;
126 6 50       23 my $start = (($line - 3) >= 0) ? ($line - 3) : 0;
127 6 50       20 my $stop = (($line + 3) < scalar(@lines)) ? ($line + 3) : scalar(@lines);
128            
129 6         23 for (my $l = $start; $l <= $stop; $l++) {
130 42         62 chomp $lines[$l];
131 42 100       65 if ($l == $line) {
132 6         19 $backtrace
133             .= qq||
134             . tabulate($l + 1, $stop + 1)
135             . qq| |
136             . _html_encode($lines[$l])
137             . "\n";
138             }
139             else {
140 36         87 my $thisline = $lines[$l];
141            
142 36 50       80 if ($thisline =~ m/^\s*#/){
143 0         0 $thisline = ''.$thisline.'';
144             }
145            
146             $backtrace
147 36         110 .= qq||
148             . tabulate($l + 1, $stop + 1)
149             . " "
150             . _html_encode($thisline) . "\n";
151             }
152             }
153 6         10 $backtrace .= "";
154 6         62 return $backtrace;
155             }
156            
157             sub _html_encode {
158 64     64   103 my $value = shift;
159 64         123 $value =~ s/&/&/g;
160 64         108 $value =~ s/
161 64         122 $value =~ s/>/>/g;
162 64         452 $value =~ s/'/'/g;
163 64         103 $value =~ s/"/"/g;
164 64         405 return $value;
165             }
166            
167             sub tabulate {
168 42     42 0 59 my ($number, $max) = @_;
169 42         51 my $len = length($max);
170 42 50       171 return $number if length($number) == $len;
171 0           return " $number";
172             }
173            
174             1;