blib/lib/CGI/HTMLError.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 10 | 71 | 14.0 |
branch | 1 | 38 | 2.6 |
condition | 1 | 21 | 4.7 |
subroutine | 4 | 6 | 66.6 |
pod | 0 | 2 | 0.0 |
total | 16 | 138 | 11.5 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package CGI::HTMLError; | ||||||
2 | |||||||
3 | 1 | 1 | 838 | use strict; | |||
1 | 2 | ||||||
1 | 75 | ||||||
4 | |||||||
5 | 1 | 1 | 6 | use vars qw($VERSION %CONF $CSS $OLD_HANDLER); | |||
1 | 2 | ||||||
1 | 92 | ||||||
6 | |||||||
7 | BEGIN { | ||||||
8 | 1 | 1 | 11 | $VERSION = '1.00'; | |||
9 | 1 | 989 | $CONF{trace} = 0; | ||||
10 | } | ||||||
11 | |||||||
12 | $CSS = ' | ||||||
27 | '; | ||||||
28 | |||||||
29 | sub import { | ||||||
30 | 1 | 1 | 9 | shift @_; | |||
31 | 1 | 50 | 33 | 13 | return unless $ENV{GATEWAY_INTERFACE} and $ENV{GATEWAY_INTERFACE} =~ /CGI/; | ||
32 | 0 | %CONF = ( %CONF, @_ ); | |||||
33 | 0 | 0 | 0 | $OLD_HANDLER = $SIG{__DIE__} if defined $SIG{__DIE__} and $SIG{__DIE__} ne 'IGNORE' and $SIG{__DIE__} ne 'DEFAULT'; | |||
0 | |||||||
34 | 0 | $SIG{__DIE__} = \ &show_source; | |||||
35 | } | ||||||
36 | |||||||
37 | sub show_source { | ||||||
38 | |||||||
39 | |||||||
40 | # | ||||||
41 | # First we try to establish if this exception might yet be cought. | ||||||
42 | # we try to do this by examining the stack trace for (eval) frames | ||||||
43 | # | ||||||
44 | # In a case of a fatal error inside an eval, this code gets | ||||||
45 | # called twice: the first time with the (eval) frame, the | ||||||
46 | # second time without. | ||||||
47 | # | ||||||
48 | |||||||
49 | 0 | 0 | 0 | my $i; | |||
50 | 0 | my ($filename_from_stack,$number_from_stack); | |||||
51 | 0 | while (1) { | |||||
52 | 0 | my @caller = caller($i++); | |||||
53 | 0 | 0 | if (defined $caller[3]) { | ||||
54 | 0 | 0 | $filename_from_stack ||= $caller[1]; | ||||
55 | 0 | 0 | $number_from_stack ||= $caller[2]; | ||||
56 | 0 | 0 | return if $caller[3] eq '(eval)'; | ||||
57 | } | ||||||
58 | else { | ||||||
59 | 0 | last; | |||||
60 | } | ||||||
61 | } | ||||||
62 | |||||||
63 | |||||||
64 | # | ||||||
65 | # now get the error string (we ignore exception objects, and just | ||||||
66 | # pray they will be stringified to a useful string) | ||||||
67 | # | ||||||
68 | |||||||
69 | 0 | my ($error) = @_; | |||||
70 | |||||||
71 | 0 | my ($filename,$number,$rest_of_error); | |||||
72 | 0 | 0 | if ($error =~ s/^(.*?\s+at\s+(.*?)\s+line\s+(\d+)[^\n]*)//s) { | ||||
73 | 0 | $rest_of_error = $error; | |||||
74 | 0 | $error = $1; | |||||
75 | 0 | $filename = $2; | |||||
76 | 0 | $number = $3; | |||||
77 | } | ||||||
78 | |||||||
79 | |||||||
80 | # | ||||||
81 | # If we haven't found the file and line in the string, just use | ||||||
82 | # the one found in the stack-trace. | ||||||
83 | # | ||||||
84 | |||||||
85 | 0 | 0 | unless ($filename) { | ||||
86 | 0 | $filename = $filename_from_stack; | |||||
87 | 0 | $number = $number_from_stack; | |||||
88 | 0 | $rest_of_error .= "Exception caused at $filename line $number"; | |||||
89 | } | ||||||
90 | |||||||
91 | |||||||
92 | |||||||
93 | # | ||||||
94 | # use the default css section or a link to another stylesheet | ||||||
95 | # | ||||||
96 | |||||||
97 | 0 | 0 | my $css = $CONF{css} ? "" : $CSS; | ||||
98 | |||||||
99 | |||||||
100 | # | ||||||
101 | # Setting status header and title.. | ||||||
102 | # | ||||||
103 | |||||||
104 | 0 | encode($error, $rest_of_error); | |||||
105 | |||||||
106 | |||||||
107 | 0 | print "Status: 500 Server Error | |||||
108 | Content-type: text/html | ||||||
109 | |||||||
110 | |
||||||
111 | $css | ||||||
112 | |||||||
113 | |||||||
114 | 500 Internal Server Error |
||||||
115 | |
||||||
116 | $error$rest_of_error |
||||||
117 | |
||||||
118 | "; | ||||||
119 | |||||||
120 | 0 | 0 | 0 | if ($filename and $number) { | |||
121 | |||||||
122 | # | ||||||
123 | # try to open the sourcefile where the error occured, | ||||||
124 | # fastforward to the apropiate line and print the section | ||||||
125 | # | ||||||
126 | |||||||
127 | 0 | 0 | if ( open SOURCE,"< $filename" ) { | ||||
128 | 0 | 0 | my $startline = $number - 10 >= 0 ? $number - 10 : 0; | ||||
129 | 0 | my $endline = $startline + 20; | |||||
130 | 0 | print 'Source:
|
|||||
131 | 0 | 0 | print "....\n" if ($startline > 1); | ||||
132 | 0 | while ( | |||||
133 | 0 | 0 | last if $. > $endline; | ||||
134 | 0 | chomp; | |||||
135 | 0 | 0 | if ($. > $startline) { | ||||
136 | 0 | encode($_); | |||||
137 | 0 | 0 | 0 | if ($. == $number) { | |||
0 | |||||||
138 | 0 | $_ = "$_"; | |||||
139 | } | ||||||
140 | elsif ($. > $number - 5 and $. < $number + 5) { | ||||||
141 | 0 | $_ = "$_"; | |||||
142 | } | ||||||
143 | 0 | printf "%04d| %s\n",$.,$_; | |||||
144 | } | ||||||
145 | } | ||||||
146 | 0 | 0 | print '....' if not eof SOURCE; | ||||
147 | 0 | close SOURCE; | |||||
148 | 0 | print ""; | |||||
149 | } | ||||||
150 | else { | ||||||
151 | 0 | print "Could not open $filename: $!"; | |||||
152 | } | ||||||
153 | } | ||||||
154 | else { | ||||||
155 | 0 | print "No filename or line number found in the error message"; | |||||
156 | } | ||||||
157 | |||||||
158 | # | ||||||
159 | # show stacktrace if a tracelevel is specified. | ||||||
160 | # | ||||||
161 | |||||||
162 | 0 | 0 | if ($CONF{trace}) { | ||||
163 | 0 | print ' Stacktrace:
|
|||||
164 | 0 | my $i; | |||||
165 | 0 | while (1) { | |||||
166 | 0 | 0 | my ($pack,$file,$number,$sub) = caller($i) or last; | ||||
167 | 0 | printf "%02d| \&$sub called at $file line $number\n",$i++; | |||||
168 | } | ||||||
169 | 0 | print ''; | |||||
170 | } | ||||||
171 | |||||||
172 | # | ||||||
173 | # end with a version identifier. | ||||||
174 | # | ||||||
175 | |||||||
176 | 0 | print " CGI::HTMLError $VERSION "; |
|||||
177 | |||||||
178 | 0 | 0 | if ($OLD_HANDLER) { | ||||
179 | 0 | $SIG{__DIE__} = $OLD_HANDLER; | |||||
180 | 0 | goto &$OLD_HANDLER; | |||||
181 | } | ||||||
182 | } | ||||||
183 | |||||||
184 | sub encode { | ||||||
185 | 0 | 0 | 0 | for (@_) { | |||
186 | 0 | s/</g; | |||||
187 | 0 | s/>/>/g; | |||||
188 | 0 | s/\n/ \n/g; |
|||||
189 | } | ||||||
190 | } | ||||||
191 | |||||||
192 | 1; | ||||||
193 | __END__ |