File Coverage

blib/lib/CGI/Application/Plugin/ErrorPage.pm
Criterion Covered Total %
statement 31 31 100.0
branch 1 2 50.0
condition n/a
subroutine 9 9 100.0
pod 1 2 50.0
total 42 44 95.4


line stmt bran cond sub pod time code
1             package CGI::Application::Plugin::ErrorPage;
2 1     1   14661 use strict;
  1         2  
  1         40  
3 1     1   6 use warnings;
  1         3  
  1         40  
4              
5             BEGIN {
6 1     1   7 use base 'Exporter';
  1         7  
  1         117  
7 1     1   2 our $VERSION = '1.21';
8 1         221 our @EXPORT_OK = 'error';
9             }
10              
11              
12             =head1 NAME
13              
14             CGI::Application::Plugin::ErrorPage - A simple error page plugin for CGI::Application
15              
16             =head1 SYNOPSIS
17              
18             use CGI::Application::Plugin::ErrorPage 'error';
19              
20             sub my_run_mode {
21             my $self = shift;
22              
23             eval { .... };
24              
25             if ($@) {
26             # Send the gory details to the log for the developers
27             warn "$@";
28            
29             # Send a comprehensible message to the users
30             return $self->error(
31             title => "Technical Failure',
32             msg => "There was a techical failure during the operation.",
33             );
34             }
35              
36             }
37              
38             =head1 DESCRIPTION
39              
40             This plugin provides a shortcut for the common need of returning a simple error
41             message to the user.
42              
43             You are encouraged to provide a template file so that the error messages can
44             be presented with a design consistent with the rest of your application.
45              
46             A simple design is provided below to get to you started.
47              
48             =head2 A better default error page.
49              
50             If you don't install an AUTOLOAD run mode in the normal way in C<< setup >>, this plugin
51             will automatically install a reasonable default at the C<< prerun >> stage, which returns an error page like this:
52              
53             return $c->error(
54             title => 'The requested page was not found.',
55             msg => "(The page tried was: ".$c->get_current_runmode.")"
56             );
57              
58             =head2 Relation to error_mode()
59              
60             CGI::Application includes C to provide custom handling when the application dies.
61             This error() routine provides a shortcut for displaying error messages to the user. So, they both have a
62             place on their own, and it could make sense to use them together. In your 'error_mode' routine, you might
63             call error() to return a message to the user:
64              
65             $self->error( title => 'Technical Failure', msg => 'There was a technical failure' );
66              
67             =head2 Suggested Uses
68              
69             Some common cases for returning error messages to the user include:
70              
71             * "Technical Failure" - The software failed unexpectedly
72             * "Insufficient Information" - some required query parameter was missing
73             * "Request Not Understood" - Some value we received in the query just didn't make sense.
74              
75             =head2 Silliness
76              
77             [22:36] Techno Failure. We were cruising along and rocking out while fulfilling your request, but then the music stopped and we sort of got distracted.
78             [22:36] Tek Failure. Too busy reading Shatner novels to respond to your request.
79              
80             =head1 METHODS
81              
82             =head2 error()
83              
84             return $self->error(
85             title => "Technical Failure',
86             msg => "There was a techical failure during the operation",
87             );
88              
89              
90             Nothing fancy, just a shortcut to load a template meant to display errors. I've used
91             it for the past several years, and it's been very handy to always have around on
92             projects to quickly write error handling code.
93              
94             It tries to load a template file named 'error.html' to display the error page.
95              
96             If you want to use a different location, I recommend putting something like this in your base class,
97             so you only have to provide your error template location once.
98              
99              
100             # In this case, intentionally *don't* import 'error' to avoid a "redefined" warning.
101             use CGI::Application::Plugin::ErrorPage;
102             sub error {
103             my $c = shift;
104             return $c->CGI::Application::Plugin::ErrorPage::error(
105             tmpl => $self->cfg('ROOT_URI').'/path/to/my/alternate/error/file.html',
106             @_,
107             );
108             }
109              
110             This module intentionally ignores any C set by application, since
111             this is usually an indication of where the intended file is located, not the
112             error template. This exceptional handling of the C is one of the
113             only value added bits of logic that this plugin adds. The rest of it is
114             primarily a simple recommendation for error page handling wrapped up as a
115             module.
116              
117             If you don't want this behavior, it's simple enough just to roll your own error() page method
118             and skip using this plugin. Here's the simple essential code:
119              
120             use Params::Validate ':all';
121             sub error {
122             my $self = shift;
123             my %p = validate(@_, { title => SCALAR, msg => SCALAR });
124             my $t = $self->load_tmpl;
125             $t->param( title => $p{title}, msg => $p{msg} );
126             return $t->output;
127             }
128              
129              
130             =cut
131              
132             sub import {
133 1     1   14 my $caller = scalar(caller);
134 1         14 $caller->add_callback('prerun', \&add_page_not_found_rm);
135 1         79 goto &Exporter::import;
136             }
137              
138             sub add_page_not_found_rm {
139 1     1 0 729 my $c = shift;
140              
141 1         9 my %rms = $c->run_modes;
142              
143 1 50       18 unless( exists $rms{'AUTOLOAD'}) {
144             $c->run_modes(
145             AUTOLOAD => sub {
146 1     1   91 my $self = shift;
147 1         10 return $self->error(
148             title => 'The requested page was not found.',
149             msg => "(The page tried was: ".$self->get_current_runmode.")"
150             )
151 1         8 });
152             }
153             }
154              
155              
156              
157              
158              
159 1     1   1101 use Params::Validate ':all';
  1         14883  
  1         489  
160             sub error {
161 2     2 1 10506 my $c = shift;
162 2         84 my %p = validate(@_, {
163             title => SCALAR,
164             msg => SCALAR,
165             # tmpl can be various types
166             tmpl => { default => 'error.html' },
167             });
168              
169             # If a tmpl_path has been set, we want to ignore it, because it was most
170             # likely meant for the template itself, not for the error page.
171            
172             # We are careful to put the value back how we found it after we are done with it here!
173              
174 2         21 my @path_to_restore = $c->tmpl_path();
175 2         22 $c->tmpl_path('');
176 2         24 my $t = $c->load_tmpl($p{tmpl});
177 2         26329 $c->tmpl_path(@path_to_restore);
178            
179 2         26 $t->param(
180             title => $p{title},
181             msg => $p{msg},
182             );
183              
184 2         604 return $t->output;
185             }
186              
187              
188              
189              
190             =head2 Example error.html
191              
192             Here's a very basic example of an C file to get you started.
193              
194            
195             PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
196             "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
197            
198            
199             <!-- tmpl_var title escape=HTML -->
200            
201            
202            
203            

204            

205            
206            
207              
208             We manage site-wide designs with Dreamweaver and keep a basic 'error.html' that
209             uses a generic Dreamweaver 'page.dwt' template with standard EditableRegion
210             names. That way, we can copy this error.html into a new Dreamweaver-managed
211             project and have the new design applied to it easily through Dreamweaver.
212              
213             =head1 SUPPORT
214              
215             Ask for help on the L mailing list. Report bugs and wishes
216             through the rt.cpan.org bug tracker.
217              
218             =head1 AUTHOR
219              
220             Mark Stosberg
221             CPAN ID: MARKSTOS
222             mark@summersault.com
223              
224             =head1 COPYRIGHT
225              
226             This program is free software; you can redistribute
227             it and/or modify it under the same terms as Perl itself.
228              
229             The full text of the license can be found in the
230             LICENSE file included with this module.
231              
232              
233             =head1 SEE ALSO
234              
235             perl(1).
236              
237             =cut
238              
239              
240             1;
241             # The preceding line will help the module return a true value
242