← Index
NYTProf Performance Profile   « line view »
For ./view
  Run on Fri Jul 31 18:42:36 2015
Reported on Fri Jul 31 18:48:14 2015

Filename/var/www/foswikidev/core/lib/Foswiki/OopsException.pm
StatementsExecuted 11 statements in 749µs
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
11112µs24µsFoswiki::OopsException::::BEGIN@91Foswiki::OopsException::BEGIN@91
11111µs35µsFoswiki::OopsException::::BEGIN@97Foswiki::OopsException::BEGIN@97
1118µs12µsFoswiki::OopsException::::BEGIN@92Foswiki::OopsException::BEGIN@92
1114µs4µsFoswiki::OopsException::::BEGIN@99Foswiki::OopsException::BEGIN@99
1113µs3µsFoswiki::OopsException::::BEGIN@94Foswiki::OopsException::BEGIN@94
0000s0sFoswiki::OopsException::::_prepareResponseFoswiki::OopsException::_prepareResponse
0000s0sFoswiki::OopsException::::generateFoswiki::OopsException::generate
0000s0sFoswiki::OopsException::::newFoswiki::OopsException::new
0000s0sFoswiki::OopsException::::redirectFoswiki::OopsException::redirect
0000s0sFoswiki::OopsException::::stringifyFoswiki::OopsException::stringify
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# See bottom of file for license and copyright information
2
3=begin TML
4
5---+ package Foswiki::OopsException
6
7Exception used to raise a request to output a preformatted page.
8
9Despite the name, =oops= is not used just for errors; it is also used
10for one-time redirection, for example during the registration process.
11
12The =Foswiki::UI::run= function, which is in the call stack for almost
13all cases where an =OopsException= will be thrown, traps the exception
14and outputs an =oops= page to the browser. This requires
15the name of a template file from the =templates= directory, which it
16expands. Parameter values passed to the exception are instantiated in
17the expanded template. The =oops= page is output with an HTTP status
18appropriate to the event that caused the exception (default 500).
19
20Extensions may throw =Foswiki::OopsException=. For example:
21
22<verbatim>
23use Error qw(:try);
24
25...
26
27throw Foswiki::OopsException( 'bathplugin',
28 status => 418,
29 web => $web,
30 topic => $topic,
31 params => [ 'big toe', 'stuck in', 'hot tap' ] );
32</verbatim>
33This will raise an exception that uses the =bathplugin.tmpl= template. If
34=UI::run= handles the exception it will generate a redirect to:
35<verbatim>
36oops?template=bathplugin;param1=bigtoe;param2=hot%20tap
37</verbatim>
38The =bathplugin.tmpl= might contain:
39(&lt;nop> inserted to prevent translation interface from extracting these examples)
40<verbatim>
41%TMPL:INCLUDE{"oops"}%
42%TMPL:DEF{"titleaction"}% %<nop>MAKETEXT{"Bathing problem"}% %TMPL:END%
43%TMPL:DEF{"heading"}%%<nop>MAKETEXT{"Problem filling bath"}%%TMPL:END%
44%TMPL:DEF{"topicactionbuttons"}%%TMPL:P{"oktopicaction"}%%TMPL:END%
45%TMPL:DEF{"script"}%<meta http-equiv="refresh" content="0;url=%SCRIPTURL{view}%/%WEB%/%TOPIC%" />%TMPL:END%
46%TMPL:DEF{"pagetitle"}%%TMPL:P{"heading"}%%TMPL:END%
47%TMPL:DEF{"webaction"}% *%<nop>MAKETEXT{"Warning"}%* %TMPL:END%
48%TMPL:DEF{"message"}%
49%<nop>MAKETEXT{"Your bath cannot be filled because your [_1] is [_2] the [_3]" args="drain,flooding,basement"}%%TMPL:END%
50</verbatim>
51In this case the =oops= page will be rendered with a 418 ("I'm a teapot")
52status in the HTTP header.
53
54A more practical example for plugins authors that does not require them to
55provide their own template file involves use of the generic message template
56available from =oopsattention.tmpl=:
57<verbatim>
58throw Foswiki::OopsException( 'oopsattention', def => 'generic',
59 params => [ Operation is not allowed ] );
60</verbatim>
61
62Note that to protect against cross site scripting all parameter values are
63automatically and unconditionally entity-encoded so you cannot pass macros
64if you need messages to be automatically translated you either need to handle
65it in the perl code before throwing Foswiki::OopsException or put the %MAKETEXT
66in the template. You cannot pass macros through the parameters.
67
68*Since* _date_ indicates where functions or parameters have been added since
69the baseline of the API (TWiki release 4.2.3). The _date_ indicates the
70earliest date of a Foswiki release that will support that function or
71parameter.
72
73*Deprecated* _date_ indicates where a function or parameters has been
74[[http://en.wikipedia.org/wiki/Deprecation][deprecated]]. Deprecated
75functions will still work, though they should
76_not_ be called in new plugins and should be replaced in older plugins
77as soon as possible. Deprecated parameters are simply ignored in Foswiki
78releases after _date_.
79
80*Until* _date_ indicates where a function or parameter has been removed.
81The _date_ indicates the latest date at which Foswiki releases still supported
82the function or parameter.
83
84=cut
85
86# THIS PACKAGE IS PART OF THE PUBLISHED API USED BY EXTENSION AUTHORS.
87# DO NOT CHANGE THE EXISTING APIS (well thought out extensions are OK)
88# AND ENSURE ALL POD DOCUMENTATION IS COMPLETE AND ACCURATE.
89
90package Foswiki::OopsException;
91227µs236µs
# spent 24µs (12+12) within Foswiki::OopsException::BEGIN@91 which was called: # once (12µs+12µs) by Foswiki::Plugin::BEGIN@15 at line 91
use strict;
# spent 24µs making 1 call to Foswiki::OopsException::BEGIN@91 # spent 12µs making 1 call to strict::import
92222µs216µs
# spent 12µs (8+4) within Foswiki::OopsException::BEGIN@92 which was called: # once (8µs+4µs) by Foswiki::Plugin::BEGIN@15 at line 92
use warnings;
# spent 12µs making 1 call to Foswiki::OopsException::BEGIN@92 # spent 4µs making 1 call to warnings::import
93
94239µs13µs
# spent 3µs within Foswiki::OopsException::BEGIN@94 which was called: # once (3µs+0s) by Foswiki::Plugin::BEGIN@15 at line 94
use Error ();
# spent 3µs making 1 call to Foswiki::OopsException::BEGIN@94
9516µsour @ISA = ('Error');
96
97247µs259µs
# spent 35µs (11+24) within Foswiki::OopsException::BEGIN@97 which was called: # once (11µs+24µs) by Foswiki::Plugin::BEGIN@15 at line 97
use Assert;
# spent 35µs making 1 call to Foswiki::OopsException::BEGIN@97 # spent 24µs making 1 call to Exporter::import
98
99
# spent 4µs within Foswiki::OopsException::BEGIN@99 which was called: # once (4µs+0s) by Foswiki::Plugin::BEGIN@15 at line 104
BEGIN {
10014µs if ( $Foswiki::cfg{UseLocale} ) {
101 require locale;
102 import locale();
103 }
1041601µs14µs}
# spent 4µs making 1 call to Foswiki::OopsException::BEGIN@99
105
106=begin TML
107
108---++ ClassMethod new( $template, ...)
109 * =template= is the name of an oops template. e.g. 'bathplugin' refers to =templates/oopsbathplugin.tmpl=
110The remaining parameters are interpreted as key-value pairs. The following keys are used:
111 * =web= will be used as the web for the oops
112 * =topic= will be used as the topic for the oops
113 * =def= - is the (optional) name of a TMPL:DEF within the template
114 * =keep= - if set, the exception handler should try its damnedest to retain parameter values from the query.
115 * =params= is a reference to an array of parameters. These will be substituted for !%PARAM1%, !%PARAM2% ... !%PARAMn% in the template.
116
117For an example of how to use the =def= parameter, see the =oopsattention=
118template.
119
120NOTE: parameter values are automatically and unconditionally entity-encoded
121
122=cut
123
124sub new {
125 my $class = shift;
126 my $template = shift;
127 my $this = $class->SUPER::new();
128 $this->{template} = $template || 'generic';
129 $this->{status} = 500; # default server error
130 ASSERT( scalar(@_) % 2 == 0, join( ";", map { $_ || 'undef' } @_ ) )
131 if DEBUG;
132 while ( my $key = shift @_ ) {
133 my $val = shift @_;
134 if ( $key eq 'params' ) {
135 if ( ref($val) ne 'ARRAY' ) {
136 $val = [$val];
137 }
138 $this->{params} = $val;
139 }
140 else {
141 $this->{$key} = $val || '';
142 }
143 }
144 return $this;
145}
146
147=begin TML
148
149---++ ObjectMethod stringify( [$session] ) -> $string
150
151Generates a string representation for the object. if a session is passed in,
152and the exception specifies a def, then that def is expanded. This is to allow
153internal expansion of oops exceptions for example when performing bulk
154operations, and also for debugging.
155
156=cut
157
158sub stringify {
159 my ( $this, $session ) = @_;
160
161 if ( $this->{template} && $this->{def} && $session ) {
162
163 # load the defs
164 $session->templates->readTemplate( 'oops' . $this->{template},
165 no_oops => 1 );
166 my $message = $session->templates->expandTemplate( $this->{def} )
167 || "Failed to find '$this->{def}' in 'oops$this->{template}'";
168 my $topicObject =
169 Foswiki::Meta->new( $session, $this->{web}, $this->{topic} );
170 $message = $topicObject->expandMacros($message);
171 my $n = 1;
172 foreach my $param ( @{ $this->{params} } ) {
173 $message =~ s/%PARAM$n%/$param/g;
174 $n++;
175 }
176 return $message;
177 }
178 else {
179 my $s = 'OopsException(';
180 $s .= $this->{template};
181 $s .= '/' . $this->{def} if $this->{def};
182 $s .= ' web=>' . $this->{web} if $this->{web};
183 $s .= ' topic=>' . $this->{topic} if $this->{topic};
184 $s .= ' keep=>1' if $this->{keep};
185 if ( defined $this->{params} ) {
186 $s .= ' params=>[' . join( ',', @{ $this->{params} } ) . ']';
187 }
188 return $s . ')' . ( (DEBUG) ? $this->stacktrace : '' );
189 }
190}
191
192# Generate a redirect to an 'oops' script for this exception.
193#
194# If the 'keep' parameter is set in the
195# exception, it saves parameter values into the query as well. This is needed
196# if the query string might get lost during a passthrough, due to a POST
197# being redirected to a GET.
198# This redirect has been replaced by the generate function below and should
199# not be called in new code.
200sub redirect {
201 my ( $this, $session ) = @_;
202
203 my @p = $this->_prepareResponse($session);
204 my $url =
205 $session->getScriptUrl( 1, 'oops', $this->{web}, $this->{topic}, @p );
206 $session->redirect( $url, 1 );
207}
208
209=begin TML
210
211---++ ObjectMethod generate( $session )
212
213Generate an error page for the exception. This will output the error page
214to the browser. The default HTTP Status for an Oops page is 500. This
215can be overridden using the 'status => ' parameter to the constructor.
216
217=cut
218
219sub generate {
220 my ( $this, $session ) = @_;
221
222 my @p = $this->_prepareResponse($session);
223 $session->{response}->status( $this->{status} );
224 require Foswiki::UI::Oops;
225 Foswiki::UI::Oops::oops( $session, $this->{web}, $this->{topic},
226 $session->{request}, 0 );
227}
228
229sub _prepareResponse {
230 my ( $this, $session ) = @_;
231 my @p = ();
232
233 $this->{template} = "oops$this->{template}"
234 unless $this->{template} =~ m/^oops/;
235 push( @p, template => $this->{template} );
236 push( @p, def => $this->{def} ) if $this->{def};
237 my $n = 1;
238 push( @p, map { 'param' . ( $n++ ) => $_ } @{ $this->{params} } );
239 while ( my $p = shift(@p) ) {
240 $session->{request}->param( -name => $p, -value => shift(@p) );
241 }
242 return @p;
243}
244
24513µs1;
246__END__