Filename | /home/mickey/git_tree/PONAPI/Server/lib/PONAPI/Exception.pm |
Statements | Executed 18 statements in 755µs |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 12µs | 3.04ms | BEGIN@4 | PONAPI::Exception::
1 | 1 | 1 | 9µs | 49µs | BEGIN@7 | PONAPI::Exception::
1 | 1 | 1 | 9µs | 40µs | BEGIN@15 | PONAPI::Exception::
1 | 1 | 1 | 8µs | 70µs | BEGIN@151 | PONAPI::Exception::
1 | 1 | 1 | 7µs | 102µs | BEGIN@5 | PONAPI::Exception::
0 | 0 | 0 | 0s | 0s | __ANON__[lib/PONAPI/Exception.pm:27] | PONAPI::Exception::
0 | 0 | 0 | 0s | 0s | __ANON__[lib/PONAPI/Exception.pm:48] | PONAPI::Exception::
0 | 0 | 0 | 0s | 0s | _bad_req | PONAPI::Exception::
0 | 0 | 0 | 0s | 0s | _handle_exception_obj | PONAPI::Exception::
0 | 0 | 0 | 0s | 0s | _moose_type_to_nice_description | PONAPI::Exception::
0 | 0 | 0 | 0s | 0s | as_response | PONAPI::Exception::
0 | 0 | 0 | 0s | 0s | as_string | PONAPI::Exception::
0 | 0 | 0 | 0s | 0s | new_from_exception | PONAPI::Exception::
0 | 0 | 0 | 0s | 0s | throw | PONAPI::Exception::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | # ABSTRACT: Exceptions for PONAPI::Server | ||||
2 | package PONAPI::Exception; | ||||
3 | |||||
4 | 2 | 53µs | 2 | 6.07ms | # spent 3.04ms (12µs+3.03) within PONAPI::Exception::BEGIN@4 which was called:
# once (12µs+3.03ms) by PONAPI::DAO::Request::Role::UpdateLike::BEGIN@7 at line 4 # spent 3.04ms making 1 call to PONAPI::Exception::BEGIN@4
# spent 3.03ms making 1 call to Moose::import |
5 | 2 | 25µs | 2 | 198µs | # spent 102µs (7+95) within PONAPI::Exception::BEGIN@5 which was called:
# once (7µs+95µs) by PONAPI::DAO::Request::Role::UpdateLike::BEGIN@7 at line 5 # spent 102µs making 1 call to PONAPI::Exception::BEGIN@5
# spent 95µs making 1 call to Sub::Exporter::__ANON__[Sub/Exporter.pm:337] |
6 | |||||
7 | 2 | 70µs | 2 | 90µs | # spent 49µs (9+40) within PONAPI::Exception::BEGIN@7 which was called:
# once (9µs+40µs) by PONAPI::DAO::Request::Role::UpdateLike::BEGIN@7 at line 7 # spent 49µs making 1 call to PONAPI::Exception::BEGIN@7
# spent 40µs making 1 call to Exporter::import |
8 | |||||
9 | sub throw { | ||||
10 | my $class_or_obj = shift; | ||||
11 | die ( blessed $class_or_obj ? $class_or_obj : $class_or_obj->new(@_) ); | ||||
12 | } | ||||
13 | |||||
14 | use overload | ||||
15 | 1 | 5µs | 1 | 31µs | # spent 40µs (9+31) within PONAPI::Exception::BEGIN@15 which was called:
# once (9µs+31µs) by PONAPI::DAO::Request::Role::UpdateLike::BEGIN@7 at line 16 # spent 31µs making 1 call to overload::import |
16 | 1 | 524µs | 1 | 40µs | fallback => 1; # spent 40µs making 1 call to PONAPI::Exception::BEGIN@15 |
17 | |||||
18 | 1 | 2µs | 1 | 1.66ms | has message => ( # spent 1.66ms making 1 call to Moose::has |
19 | is => 'ro', | ||||
20 | isa => 'Str', | ||||
21 | required => 1, | ||||
22 | ); | ||||
23 | |||||
24 | has status => ( | ||||
25 | is => 'ro', | ||||
26 | isa => 'Int', | ||||
27 | default => sub { 400 }, | ||||
28 | 1 | 3µs | 1 | 6.79ms | ); # spent 6.79ms making 1 call to Moose::has |
29 | |||||
30 | 1 | 2µs | 1 | 1.38ms | has bad_request_data => ( # spent 1.38ms making 1 call to Moose::has |
31 | is => 'ro', | ||||
32 | isa => 'Bool', | ||||
33 | ); | ||||
34 | |||||
35 | 1 | 2µs | 1 | 1.25ms | has sql_error => ( # spent 1.25ms making 1 call to Moose::has |
36 | is => 'ro', | ||||
37 | isa => 'Bool', | ||||
38 | ); | ||||
39 | |||||
40 | 1 | 2µs | 1 | 1.23ms | has internal => ( # spent 1.23ms making 1 call to Moose::has |
41 | is => 'ro', | ||||
42 | isa => 'Bool', | ||||
43 | ); | ||||
44 | |||||
45 | has json_api_version => ( | ||||
46 | is => 'ro', | ||||
47 | isa => 'Str', | ||||
48 | default => sub { '1.0' }, | ||||
49 | 1 | 4µs | 1 | 2.21ms | writer => '_set_json_api_version' # spent 2.21ms making 1 call to Moose::has |
50 | ); | ||||
51 | |||||
52 | # Picked from Throwable::Error | ||||
53 | sub as_string { | ||||
54 | my $self = shift; | ||||
55 | return $self->message; | ||||
56 | } | ||||
57 | |||||
58 | sub as_response { | ||||
59 | my $self = shift; | ||||
60 | |||||
61 | my $status = $self->status; | ||||
62 | my $detail = $self->message; | ||||
63 | |||||
64 | if ( $self->sql_error ) { | ||||
65 | $detail = "SQL error: $detail"; | ||||
66 | } | ||||
67 | elsif ( $self->bad_request_data ) { | ||||
68 | $detail = "Bad request data: $detail"; | ||||
69 | } | ||||
70 | else { | ||||
71 | $status = 500; | ||||
72 | warn $detail if $detail; | ||||
73 | $detail = "A fatal error has occured, please check server logs"; | ||||
74 | } | ||||
75 | |||||
76 | return $status, [], +{ | ||||
77 | jsonapi => { version => $self->json_api_version }, | ||||
78 | errors => [ { detail => $detail, status => $status } ], | ||||
79 | }; | ||||
80 | } | ||||
81 | |||||
82 | sub new_from_exception { | ||||
83 | my ( $class, $e ) = @_; | ||||
84 | |||||
85 | return $e if blessed($e) && $e->isa($class); | ||||
86 | |||||
87 | my %args_for_new = $class->_handle_exception_obj($e); | ||||
88 | |||||
89 | unless ( $args_for_new{status} and $args_for_new{message} ) { | ||||
90 | %args_for_new = ( | ||||
91 | status => 500, | ||||
92 | message => '', | ||||
93 | ); | ||||
94 | warn "$e"; | ||||
95 | } | ||||
96 | |||||
97 | return $class->new(%args_for_new); | ||||
98 | } | ||||
99 | |||||
100 | sub _handle_exception_obj { | ||||
101 | my ( $self, $e ) = @_; | ||||
102 | return unless blessed($e) or $e->isa('Moose::Exception'); | ||||
103 | |||||
104 | if ( $e->isa('Moose::Exception::AttributeIsRequired') ) { | ||||
105 | my $attribute = $e->attribute_name; | ||||
106 | return _bad_req( "Parameter `$attribute` is required" ); | ||||
107 | } | ||||
108 | elsif ( | ||||
109 | $e->isa('Moose::Exception::ValidationFailedForTypeConstraint') or | ||||
110 | $e->isa('Moose::Exception::ValidationFailedForInlineTypeConstraint') | ||||
111 | ) { | ||||
112 | my $class = find_meta( $e->class_name ); | ||||
113 | my $attribute = $class->get_attribute( $e->attribute_name ); | ||||
114 | my $value_nice = JSON::XS->new->allow_nonref->utf8->canonical->encode( $e->value ); | ||||
115 | |||||
116 | if ( !$attribute ) { | ||||
117 | my $attr = $e->attribute_name; | ||||
118 | return _bad_req( "Parameter `$attr` got an expected data type: $value_nice" ); | ||||
119 | } | ||||
120 | |||||
121 | my $attribute_name = $attribute->name; | ||||
122 | my $type_name = _moose_type_to_nice_description( $attribute->{isa} ); | ||||
123 | |||||
124 | return _bad_req( "Parameter `$attribute_name` expected $type_name, but got a $value_nice" ); | ||||
125 | } | ||||
126 | |||||
127 | return; | ||||
128 | } | ||||
129 | |||||
130 | sub _bad_req { | ||||
131 | return ( | ||||
132 | message => shift, | ||||
133 | status => 400, | ||||
134 | bad_request_data => 1, | ||||
135 | ); | ||||
136 | } | ||||
137 | |||||
138 | # THIS IS NOT COMPLETE, NOR IS IT MEANT TO BE | ||||
139 | sub _moose_type_to_nice_description { | ||||
140 | my ($type_name) = @_; | ||||
141 | |||||
142 | $type_name =~ s/ArrayRef/Collection/g; | ||||
143 | $type_name =~ s/HashRef/Resource/g; | ||||
144 | $type_name =~ s/Maybe\[(.+)]/null or $1/g; | ||||
145 | $type_name =~ s/\|/ or /g; | ||||
146 | |||||
147 | return $type_name; | ||||
148 | } | ||||
149 | |||||
150 | 1 | 3µs | 2 | 7.48ms | __PACKAGE__->meta->make_immutable; # spent 7.47ms making 1 call to Class::MOP::Class::make_immutable
# spent 12µs making 1 call to PONAPI::Exception::meta |
151 | 3 | 62µs | 2 | 132µs | # spent 70µs (8+62) within PONAPI::Exception::BEGIN@151 which was called:
# once (8µs+62µs) by PONAPI::DAO::Request::Role::UpdateLike::BEGIN@7 at line 151 # spent 70µs making 1 call to PONAPI::Exception::BEGIN@151
# spent 62µs making 1 call to Moose::unimport |
152 | |||||
153 | __END__ |