File Coverage

blib/lib/Kelp/Exception.pm
Criterion Covered Total %
statement 13 13 100.0
branch 2 2 100.0
condition 2 3 66.6
subroutine 4 4 100.0
pod 1 2 50.0
total 22 24 91.6


line stmt bran cond sub pod time code
1             package Kelp::Exception;
2              
3 1     1   21327 use Kelp::Base;
  1         3  
  1         12  
4              
5 1     1   81 use Carp;
  1         3  
  1         320  
6              
7             attr -code => sub { croak 'code is required' };
8              
9             attr 'body';
10              
11             sub new {
12 13     13 0 45 my ($class, $code, %params) = @_;
13              
14 13 100 66     274 croak 'Kelp::Exception can only accept 4XX or 5XX codes'
15             unless defined $code && $code =~ /^[45]\d\d$/;
16              
17 12         32 $params{code} = $code;
18 12         49 return $class->SUPER::new(%params);
19             }
20              
21             sub throw {
22 13     13 1 99 my $class = shift;
23 13         31 my $ex = $class->new(@_);
24 12         70 die $ex;
25             }
26              
27             1;
28              
29             __END__
30              
31             =pod
32              
33             =head1 NAME
34              
35             Kelp::Exception - Tiny HTTP exceptions
36              
37             =head1 SYNOPSIS
38              
39             Exception->throw(400, body => 'The request was malformed');
40              
41             # code is optional - 500 by default
42             Kelp::Exception->throw;
43              
44             # can control what user sees - even in deployment (unlike string exceptions)
45             Kelp::Exception->throw(501, body => {
46             status => \0,
47             error => 'This method is not yet implemented'
48             });
49              
50             =head1 DESCRIPTION
51              
52             This module offers a fine-grained control of what the user sees when an
53             exception occurs. Generally, this could also be done by setting the
54             result code manually, but that requires passing the Kelp instance around and
55             does not immediately end the handling code. Exceptions are a way to end route
56             handler execution from deep within the call stack.
57              
58             This implementation is very incomplete and can only handle 4XX and 5XX status
59             codes, meaning that you can't do redirects and normal responses like this. It
60             also tries to maintain some degree of compatibility with L<HTTP::Exception>
61             without its complexity.
62              
63             =head1 ATTRIBUTES
64              
65             =head2 code
66              
67             HTTP status code. Only possible are 5XX and 4XX.
68              
69             Readonly.
70              
71             =head2 body
72              
73             Required. Body of the request - can be a string for HTML and a hashref /
74             arrayref for JSON responses.
75              
76             A string will be passed to C<< $response->render_error >> to be rendered inside
77             an error template, if available. A reference will be JSON encoded if JSON is
78             available, otherwise will produce an exception.
79              
80             Content type for the response will be set accordingly.
81              
82             =head1 METHODS
83              
84             =head2 throw
85              
86             # both do exactly the same
87             Kelp::Exception->throw(...);
88             die Kelp::Exception->new(...);
89              
90             Same as simply constructing and calling die on an object.
91              
92             =head1 CAVEATS
93              
94             =over
95              
96             =item
97              
98             Code 500 exceptions will not be logged, as it is considered something that a
99             web developer know about. They are not thrown anywhere in Kelp internal code,
100             so only user code can fall victim to this.
101              
102             =item
103              
104             If there is no content type set, and the exception body is not a reference,
105             then a C<text/html> content type will be guessed and the body text will be
106             passed to an error template, if available.
107              
108             =back
109              
110             =cut
111              
112