File Coverage

blib/lib/CGI/Carp/WarningsToBrowser.pm
Criterion Covered Total %
statement 13 22 59.0
branch 2 8 25.0
condition 1 6 16.6
subroutine 5 6 83.3
pod n/a
total 21 42 50.0


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;