Profile of lib/PONAPI/Exception.pm

← Index
NYTProf Performance Profile «line view»
For script/ponapi
Run on Wed Feb 10 15:51:26 2016
Reported on Thu Feb 11 09:43:11 2016

Filename | /home/mickey/git_tree/PONAPI/Server/lib/PONAPI/Exception.pm
Statements | Executed 18 statements in 755µs

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
1 | 1 | 1 | 12µs | 3.04ms | PONAPI::Exception::::BEGIN@4PONAPI::Exception::BEGIN@4
1 | 1 | 1 | 9µs | 49µs | PONAPI::Exception::::BEGIN@7PONAPI::Exception::BEGIN@7
1 | 1 | 1 | 9µs | 40µs | PONAPI::Exception::::BEGIN@15PONAPI::Exception::BEGIN@15
1 | 1 | 1 | 8µs | 70µs | PONAPI::Exception::::BEGIN@151PONAPI::Exception::BEGIN@151
1 | 1 | 1 | 7µs | 102µs | PONAPI::Exception::::BEGIN@5PONAPI::Exception::BEGIN@5
0 | 0 | 0 | 0s | 0s | PONAPI::Exception::::__ANON__[lib/PONAPI/Exception.pm:27]PONAPI::Exception::__ANON__[lib/PONAPI/Exception.pm:27]
0 | 0 | 0 | 0s | 0s | PONAPI::Exception::::__ANON__[lib/PONAPI/Exception.pm:48]PONAPI::Exception::__ANON__[lib/PONAPI/Exception.pm:48]
0 | 0 | 0 | 0s | 0s | PONAPI::Exception::::_bad_reqPONAPI::Exception::_bad_req
0 | 0 | 0 | 0s | 0s | PONAPI::Exception::::_handle_exception_objPONAPI::Exception::_handle_exception_obj
0 | 0 | 0 | 0s | 0s | PONAPI::Exception::::_moose_type_to_nice_descriptionPONAPI::Exception::_moose_type_to_nice_description
0 | 0 | 0 | 0s | 0s | PONAPI::Exception::::as_responsePONAPI::Exception::as_response
0 | 0 | 0 | 0s | 0s | PONAPI::Exception::::as_stringPONAPI::Exception::as_string
0 | 0 | 0 | 0s | 0s | PONAPI::Exception::::new_from_exceptionPONAPI::Exception::new_from_exception
0 | 0 | 0 | 0s | 0s | PONAPI::Exception::::throwPONAPI::Exception::throw

Call graph for these subroutines as a Graphviz dot language file.

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 use Moose; # 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 use Moose::Util qw/find_meta/; # 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 use JSON::XS; # 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 q{""} => 'as_string', # 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 no Moose; 1; # spent 70µs making 1 call to PONAPI::Exception::BEGIN@151 # spent 62µs making 1 call to Moose::unimport
152 |  |  |  |  |
153 |  |  |  |  | __END__