line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package CGI::Carp::WarningsToBrowser; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
our $VERSION = 0.02; |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=pod |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
=head1 NAME |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
CGI::Carp::WarningsToBrowser - A version of L's warningsToBrowser() |
10
|
|
|
|
|
|
|
that displays the warnings loudly and boldly |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=head1 RATIONALE |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
The author feels that it's important to expose warnings as early as possible in |
15
|
|
|
|
|
|
|
the software development lifecycle, preferably by the same developer who created |
16
|
|
|
|
|
|
|
them, as part of the "L" effort. |
17
|
|
|
|
|
|
|
"Shift left" basically means that the earlier in the SDLC that a problem can be |
18
|
|
|
|
|
|
|
found, the cheaper it is to fix it. |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 SYNOPSIS |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
Put this at the top of your CGI script (the earlier the better, otherwise some |
23
|
|
|
|
|
|
|
warnings might not get captured): |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
use CGI::Carp::WarningsToBrowser; |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
Warnings will now be displayed at the very top of the web page, rather than |
28
|
|
|
|
|
|
|
hidden in HTML comments like L's version. This is intended mainly |
29
|
|
|
|
|
|
|
for dev and test environments, not for prod, so it's a good idea to use L: |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
use if $is_dev, 'CGI::Carp::WarningsToBrowser'; |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
=head1 HANDLING ERRORS |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
This module does not handle fatal errors, because L does an adequate |
36
|
|
|
|
|
|
|
job at that task. |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
=head1 COMPATIBILITY |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
Javascript must be enabled on the browser side, otherwise the warnings will |
41
|
|
|
|
|
|
|
appear at the very bottom of the document. (the warnings are actually output in |
42
|
|
|
|
|
|
|
an C block, and three lines of Javascript are used to move them to the |
43
|
|
|
|
|
|
|
top of the HTML page) |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
=head1 AUTHOR |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
Dee Newcum |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=head1 CONTRIBUTING |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
Please use L |
52
|
|
|
|
|
|
|
to file both bugs and feature requests. Contributions to the project in form of |
53
|
|
|
|
|
|
|
Github's pull requests are welcome. |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
=head1 LICENSE |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
This library is free software; you may redistribute it and/or modify it under |
58
|
|
|
|
|
|
|
the same terms as Perl itself. |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
=cut |
61
|
|
|
|
|
|
|
|
62
|
1
|
|
|
1
|
|
617
|
use strict; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
23
|
|
63
|
1
|
|
|
1
|
|
4
|
use warnings; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
22
|
|
64
|
|
|
|
|
|
|
|
65
|
1
|
|
|
1
|
|
386
|
use HTML::Entities 3.00 (); |
|
1
|
|
|
|
|
4255
|
|
|
1
|
|
|
|
|
201
|
|
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
our @WARNINGS; |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
sub import { |
70
|
|
|
|
|
|
|
# if we're under the debugger, don't interfere with the warnings |
71
|
1
|
0
|
33
|
1
|
|
11
|
return if (exists $INC{'perl5db.pl'} && $DB::{single}); |
72
|
|
|
|
|
|
|
# if we're under perl -c, don't interfere with the warnings |
73
|
1
|
50
|
|
|
|
5
|
return if ($^C); |
74
|
1
|
|
|
|
|
9
|
$main::SIG{__WARN__} = \&_handle_warn; |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
sub _handle_warn { |
79
|
0
|
|
|
0
|
|
0
|
push @WARNINGS, shift; |
80
|
|
|
|
|
|
|
} |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
END { |
84
|
|
|
|
|
|
|
_print_warnings(); |
85
|
|
|
|
|
|
|
} |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
sub _print_warnings { |
89
|
1
|
50
|
|
1
|
|
26
|
return unless (@WARNINGS); |
90
|
|
|
|
|
|
|
# TODO: Hopefully we have output a text/html document. Is there a way to |
91
|
|
|
|
|
|
|
# detect this, and avoid printing on other kinds of documents (which could |
92
|
|
|
|
|
|
|
# corrupt file downloads, for example) |
93
|
|
|
|
|
|
|
# see -- Tie::StdHandle or Tie::Handle::Base |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
# TODO: What do we do about encoding? Is there a way to auto-detect what |
96
|
|
|
|
|
|
|
# kind of encoding was specified? Or should we just use |
97
|
|
|
|
|
|
|
# Unicode::Diacritic::Strip (to strip diacritics) and/or Text::Unidecode (to |
98
|
|
|
|
|
|
|
# output string-representations of non-ASCII Unicode characters)? |
99
|
|
|
|
|
|
|
# see -- Tie::StdHandle or Tie::Handle::Base |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
# In some situations, the HTTP response header won't have been output yet. |
102
|
|
|
|
|
|
|
# Try to auto-detect this. |
103
|
0
|
|
|
|
|
|
my $bytes_written = tell(STDOUT); |
104
|
0
|
0
|
0
|
|
|
|
if (!defined($bytes_written) || $bytes_written <= 0) { |
105
|
|
|
|
|
|
|
# The HTTP response header *probably* hasn't been output yet, so output |
106
|
|
|
|
|
|
|
# one of our own. |
107
|
|
|
|
|
|
|
# (though see https://perldoc.perl.org/functions/tell for caveats) |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
# TODO: Do we want to output an encoding along with this? |
110
|
0
|
|
|
|
|
|
print STDOUT "Status: 500\n"; |
111
|
0
|
|
|
|
|
|
print STDOUT "Content-type: text/html\n\n"; |
112
|
|
|
|
|
|
|
} |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
# print the warning-header |
115
|
0
|
|
|
|
|
|
print STDOUT <<'EOF'; |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
Perl warnings |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
EOF |
120
|
0
|
|
|
|
|
|
foreach my $warning (@WARNINGS) { |
121
|
0
|
|
|
|
|
|
print STDOUT HTML::Entities::encode_entities($warning); |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
# print the warning-footer |
125
|
0
|
|
|
|
|
|
print STDOUT <<'EOF'; |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
EOF |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
1; |