line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package HTTP::Exception; |
2
|
|
|
|
|
|
|
$HTTP::Exception::VERSION = '0.04006'; |
3
|
27
|
|
|
27
|
|
677945
|
use strict; |
|
27
|
|
|
|
|
71
|
|
|
27
|
|
|
|
|
1040
|
|
4
|
27
|
|
|
27
|
|
26701
|
use HTTP::Status; |
|
27
|
|
|
|
|
120899
|
|
|
27
|
|
|
|
|
9944
|
|
5
|
27
|
|
|
27
|
|
429
|
use Scalar::Util qw(blessed); |
|
27
|
|
|
|
|
50
|
|
|
27
|
|
|
|
|
10613
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
################################################################################ |
8
|
|
|
|
|
|
|
sub import { |
9
|
28
|
|
|
28
|
|
48439
|
my ($class) = shift; |
10
|
28
|
|
|
|
|
17386
|
require HTTP::Exception::Loader; |
11
|
28
|
|
|
|
|
282
|
HTTP::Exception::Loader->import(@_); |
12
|
|
|
|
|
|
|
} |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
# act as a kind of factory here |
15
|
|
|
|
|
|
|
sub new { |
16
|
34
|
|
|
34
|
1
|
56150
|
my $class = shift; |
17
|
34
|
|
|
|
|
65
|
my $error_code = shift; |
18
|
|
|
|
|
|
|
|
19
|
34
|
100
|
|
|
|
146
|
die ('HTTP::Exception->throw needs a HTTP-Statuscode to throw') unless ($error_code); |
20
|
32
|
100
|
|
|
|
139
|
die ("Unknown HTTP-Statuscode: $error_code") unless (HTTP::Status::status_message ($error_code)); |
21
|
|
|
|
|
|
|
|
22
|
30
|
|
|
|
|
587
|
"HTTP::Exception::$error_code"->new(@_); |
23
|
|
|
|
|
|
|
} |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# makes HTTP::Exception->caught possible instead of HTTP::Exception::Base->caught |
26
|
|
|
|
|
|
|
sub caught { |
27
|
131
|
|
|
131
|
0
|
5570
|
my $self = shift; |
28
|
131
|
|
|
|
|
286
|
my $e = $@; |
29
|
131
|
100
|
100
|
|
|
1762
|
return $e if (blessed $e && $e->isa('HTTP::Exception::Base')); |
30
|
3
|
|
|
|
|
29
|
$self->SUPER::caught(@_); |
31
|
|
|
|
|
|
|
} |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
1; |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
=head1 NAME |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
HTTP::Exception - throw HTTP-Errors as (Exception::Class-) Exceptions |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
=head1 VERSION |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
version 0.04006 |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
=begin readme |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
=head1 INSTALLATION |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
To install this module, run the following commands: |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
perl Build.PL |
51
|
|
|
|
|
|
|
./Build |
52
|
|
|
|
|
|
|
./Build test |
53
|
|
|
|
|
|
|
./Build install |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
=end readme |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
=head1 SYNOPSIS |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
HTTP::Exception lets you throw HTTP-Errors as Exceptions. |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
use HTTP::Exception; |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
# throw a 404 Exception |
64
|
|
|
|
|
|
|
HTTP::Exception->throw(404); |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
# later in your framework |
67
|
|
|
|
|
|
|
eval { ... }; |
68
|
|
|
|
|
|
|
if (my $e = HTTP::Exception->caught) { |
69
|
|
|
|
|
|
|
# do some errorhandling stuff |
70
|
|
|
|
|
|
|
print $e->code; # 404 |
71
|
|
|
|
|
|
|
print $e->status_message; # Not Found |
72
|
|
|
|
|
|
|
} |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
You can also throw HTTP::Exception-subclasses like this. |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
# same 404 Exception |
77
|
|
|
|
|
|
|
eval { HTTP::Exception::404->throw(); }; |
78
|
|
|
|
|
|
|
eval { HTTP::Exception::NOT_FOUND->throw(); }; |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
And catch them accordingly. |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
# same 404 Exception |
83
|
|
|
|
|
|
|
eval { HTTP::Exception::404->throw(); }; |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
if (my $e = HTTP::Exception::405->caught) { do stuff } # won't catch |
86
|
|
|
|
|
|
|
if (my $e = HTTP::Exception::404->caught) { do stuff } # will catch |
87
|
|
|
|
|
|
|
if (my $e = HTTP::Exception::NOT_FOUND->caught) { do stuff } # will catch |
88
|
|
|
|
|
|
|
if (my $e = HTTP::Exception::4XX->caught) { do stuff } # will catch all 4XX Exceptions |
89
|
|
|
|
|
|
|
if (my $e = HTTP::Exception->caught) { do stuff } # will catch every HTTP::Exception |
90
|
|
|
|
|
|
|
if (my $e = Exception::Class->caught) { do stuff } # catch'em all |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
You can create Exceptions and not throw them, because maybe you want to set some |
93
|
|
|
|
|
|
|
fields manually. See L and |
94
|
|
|
|
|
|
|
L for more info. |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
# is not thrown, ie doesn't die, only created |
97
|
|
|
|
|
|
|
my $e = HTTP::Exception->new(404); |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
# usual stuff works |
100
|
|
|
|
|
|
|
$e->code; # 404 |
101
|
|
|
|
|
|
|
$e->status_message # Not Found |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
# set status_message to something else |
104
|
|
|
|
|
|
|
$e->status_message('Nothing Here') |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
# fails, because code is only an accessor, see section ACCESSORS below |
107
|
|
|
|
|
|
|
# $e->code(403); |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
# and finally throw our prepared exception |
110
|
|
|
|
|
|
|
$e->throw; |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
=head1 DESCRIPTION |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
Every HTTP::Exception is a L - Class. So the same mechanisms |
115
|
|
|
|
|
|
|
apply as with L-classes. In fact have a look at |
116
|
|
|
|
|
|
|
L' docs for more general information on exceptions and |
117
|
|
|
|
|
|
|
L for information on what methods a caught exception |
118
|
|
|
|
|
|
|
also has. |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
HTTP::Exception is only a factory for HTTP::Exception::XXX (where X is a number) |
121
|
|
|
|
|
|
|
subclasses. That means that HTTP::Exception->new(404) returns a |
122
|
|
|
|
|
|
|
HTTP::Exception::404 object, which in turn is a HTTP::Exception::Base - Object. |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
Don't bother checking a caught HTTP::Exception::...-class with "isa" as it might |
125
|
|
|
|
|
|
|
not contain what you would expect. Use the code- or status_message-attributes |
126
|
|
|
|
|
|
|
and the is_ -methods instead. |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
The subclasses are created at compile-time, ie the first time you make |
129
|
|
|
|
|
|
|
"use HTTP::Exception". See paragraph below for the naming scheme of those |
130
|
|
|
|
|
|
|
subclasses. |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
Subclassing the subclasses works as expected. |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
=head1 NAMING SCHEME |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
=head2 HTTP::Exception::XXX |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
X is a Number and XXX is a valid HTTP-Statuscode. All HTTP-Statuscodes are |
139
|
|
|
|
|
|
|
supported. See chapter L |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
=head2 HTTP::Exception::STATUS_MESSAGE |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
STATUS_MESSAGE is the same name as a L Constant B |
144
|
|
|
|
|
|
|
the HTTP_ at the beginning. So see L for more details. |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
=head1 IMPORTING SPECIFIC ERROR RANGES |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
It is possible to load only specific ranges of errors. For example |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
use HTTP::Exception qw(5XX); |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
HTTP::Exception::500->throw; # works |
153
|
|
|
|
|
|
|
HTTP::Exception::400->throw; # won't work anymore |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
will only create HTTP::Exception::500 till HTTP::Exception::510. In theory this |
156
|
|
|
|
|
|
|
should save some memory, but I don't have any numbers, that back up this claim. |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
You can load multiple ranges |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
use HTTP::Exception qw(3XX 4XX 5XX); |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
And there are aliases for ranges |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
use HTTP::Exception qw(CLIENT_ERROR) |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
The following aliases exist and load the specified ranges: |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
REDIRECTION => 3XX |
169
|
|
|
|
|
|
|
CLIENT_ERROR => 4XX |
170
|
|
|
|
|
|
|
SERVER_ERROR => 5XX |
171
|
|
|
|
|
|
|
ERROR => 4XX 5XX |
172
|
|
|
|
|
|
|
ALL => 1XX 2XX 3XX 4XX 5XX |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
And of course, you can load multiple aliased ranges |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
use HTTP::Exception qw(REDIRECTION ERROR) |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
ALL is the same as not specifying any specific range. |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
# the same |
181
|
|
|
|
|
|
|
use HTTP::Exception qw(ALL); |
182
|
|
|
|
|
|
|
use HTTP::Exception; |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
=head1 ACCESSORS (READONLY) |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
=head2 code |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
A valid HTTP-Statuscode. See L for information on what codes exist. |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
=head2 is_info |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
Return TRUE if C<$self->code> is an I status code (1xx). This |
193
|
|
|
|
|
|
|
class of status code indicates a provisional response which can't have |
194
|
|
|
|
|
|
|
any content. |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
=head2 is_success |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
Return TRUE if C<$self->code> is a I status code (2xx). |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
=head2 is_redirect |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
Return TRUE if C<$self->code> is a I status code (3xx). This class |
203
|
|
|
|
|
|
|
if status code indicates that further action needs to be taken by the |
204
|
|
|
|
|
|
|
user agent in order to fulfill the request. |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
=head2 is_error |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
Return TRUE if C<$self->code> is an I status code (4xx or 5xx). The |
209
|
|
|
|
|
|
|
function return TRUE for both client error or a server error status codes. |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
=head2 is_client_error |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
Return TRUE if C<$self->code> is an I status code (4xx). This |
214
|
|
|
|
|
|
|
class of status code is intended for cases in which the client seems to |
215
|
|
|
|
|
|
|
have erred. |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
=head2 is_server_error |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
Return TRUE if C<$self->code> is an I status code (5xx). This |
220
|
|
|
|
|
|
|
class of status codes is intended for cases in which the server is aware |
221
|
|
|
|
|
|
|
that it has erred or is incapable of performing the request. |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
I, so check back there and |
224
|
|
|
|
|
|
|
alert me of changes.> |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
=head1 FIELDS |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
Fields are the same as ACCESSORS except they can be set. Either you set them |
229
|
|
|
|
|
|
|
during Exception creation (->new) or Exception throwing (->throw). |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
HTTP::Exception->new(200, status_message => "Everything's fine"); |
232
|
|
|
|
|
|
|
HTTP::Exception::200->new(status_message => "Everything's fine"); |
233
|
|
|
|
|
|
|
HTTP::Exception::OK->new(status_message => "Everything's fine"); |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
HTTP::Exception->throw(200, status_message => "Everything's fine"); |
236
|
|
|
|
|
|
|
HTTP::Exception::200->throw(status_message => "Everything's fine"); |
237
|
|
|
|
|
|
|
HTTP::Exception::OK->throw(status_message => "Everything's fine"); |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
Catch them in your Webframework like this |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
eval { ... } |
242
|
|
|
|
|
|
|
if (my $e = HTTP::Exception->caught) { |
243
|
|
|
|
|
|
|
print $e->code; # 200 |
244
|
|
|
|
|
|
|
print $e->status_message # "Everything's fine" instead of the usual ok |
245
|
|
|
|
|
|
|
} |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
=head2 status_message |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
B The HTTP-Statusmessage as provided by L |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
A Message, that represents the Execptions' Status for Humans. |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
=head1 PLACK |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
HTTP::Exception can be used with L. But |
256
|
|
|
|
|
|
|
HTTP::Exception does not depend on L, you can use it anywhere else. It |
257
|
|
|
|
|
|
|
just plays nicely with L. |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
=head1 COMPLETENESS |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
For the sake of completeness, HTTP::Exception provides exceptions for |
262
|
|
|
|
|
|
|
non-error-http-statuscodes. This means you can do |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
HTTP::Exception->throw(200); |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
which throws an Exception of type OK. Maybe useless, but complete. |
267
|
|
|
|
|
|
|
A more realworld-example would be a redirection |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
# all are exactly the same |
270
|
|
|
|
|
|
|
HTTP::Exception->throw(301, location => 'google.com'); |
271
|
|
|
|
|
|
|
HTTP::Exception::301->throw(location => 'google.com'); |
272
|
|
|
|
|
|
|
HTTP::Exception::MOVED_PERMANENTLY->throw(location => 'google.com'); |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
=head1 CAVEATS |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
The HTTP::Exception-Subclass-Creation relies on L. |
277
|
|
|
|
|
|
|
It's possible that the Subclasses change, when HTTP::Status' |
278
|
|
|
|
|
|
|
constants are changed. |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
New Subclasses are created automatically, when constants are added to |
281
|
|
|
|
|
|
|
HTTP::Status. That means in turn, that Subclasses disappear, when constants |
282
|
|
|
|
|
|
|
are removed from L. |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
Some constants were added to L' in February 2012. As a result |
285
|
|
|
|
|
|
|
HTTP::Exception broke. But that was the result of uncareful coding on my side. |
286
|
|
|
|
|
|
|
I think, that breaking changes are now quite unlikely. |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
=head1 AUTHOR |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
Thomas Mueller, C<< >> |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
=head1 SEE ALSO |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
=head2 L, L |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
Consult Exception::Class' documentation for the Exception-Mechanism and |
297
|
|
|
|
|
|
|
Exception::Class::Base' docs for a list of methods our caught Exception is also |
298
|
|
|
|
|
|
|
capable of. |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
=head2 L |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
Constants, Statuscodes and Statusmessages |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
=head2 L, especially L |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
Have a look at Plack, because it rules in general. In the first place, this |
307
|
|
|
|
|
|
|
Module was written as the companion for L, |
308
|
|
|
|
|
|
|
but since it doesn't depend on Plack, you can use it anywhere else, too. |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
=head1 BUGS |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
Please report any bugs or feature requests to |
313
|
|
|
|
|
|
|
C, or through the web interface at |
314
|
|
|
|
|
|
|
L. |
315
|
|
|
|
|
|
|
I will be notified, and then you'll automatically be notified of progress on |
316
|
|
|
|
|
|
|
your bug as I make changes. |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
=head1 SUPPORT |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
perldoc HTTP::Exception |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
You can also look for information at: |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
=over 4 |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
L |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
L |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
=item * CPAN Ratings |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
L |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
=item * Search CPAN |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
L |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
=back |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
=head1 LICENSE AND COPYRIGHT |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
Copyright 2010 Thomas Mueller. |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
351
|
|
|
|
|
|
|
under the terms of either: the GNU General Public License as published |
352
|
|
|
|
|
|
|
by the Free Software Foundation; or the Artistic License. |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
See http://dev.perl.org/licenses/ for more information. |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
=cut |