File Coverage

blib/lib/Paws/Net/RestJsonResponse.pm
Criterion Covered Total %
statement 71 103 68.9
branch 47 72 65.2
condition 4 7 57.1
subroutine 9 10 90.0
pod 0 6 0.0
total 131 198 66.1


line stmt bran cond sub pod time code
1             package Paws::Net::RestJsonResponse;
2 7     7   16044 use Moose::Role;
  7         22  
  7         62  
3 7     7   37552 use JSON::MaybeXS;
  7         20  
  7         453  
4 7     7   46 use Carp qw(croak);
  7         17  
  7         357  
5 7     7   44 use Paws::Exception;
  7         14  
  7         13602  
6              
7             sub handle_response {
8 38     38 0 45708 my ($self, $call_object, $http_status, $content, $headers) = @_;
9              
10 38 50       147 if (defined $headers->{ 'x-amz-crc32' }) {
11 0         0 require String::CRC32;
12 0         0 my $crc = String::CRC32::crc32($content);
13             return Paws::Exception->new(
14             code => 'Crc32Error',
15             message => 'Content CRC32 mismatch',
16             request_id => $headers->{ 'x-amzn-requestid' }
17 0 0       0 ) if ($crc != $headers->{ 'x-amz-crc32' });
18             }
19              
20 38 100       127 if ( $http_status >= 300 ) {
21 21         144 return $self->error_to_exception($call_object, $http_status, $content, $headers);
22             } else {
23 17         81 return $self->response_to_object($call_object, $http_status, $content, $headers);
24             }
25             }
26            
27             sub unserialize_response {
28 32     32 0 91 my ($self, $data) = @_;
29              
30 32         473 return decode_json( $data );
31             }
32              
33             sub error_to_exception {
34 21     21 0 51 my ($self, $call_object, $http_status, $content, $headers) = @_;
35            
36 21         38 my $struct = eval { $self->unserialize_response( $content ) };
  21         55  
37 21 100       66 if ($@) {
38 12         216 return Paws::Exception->new(
39             message => $@,
40             code => 'InvalidContent',
41             request_id => '', #$request_id,
42             http_status => $http_status,
43             );
44             }
45              
46 9         24 my ($message, $request_id, $code);
47              
48 9 100       34 if (exists $struct->{message}){
    50          
49 5         14 $message = $struct->{message};
50             } elsif (exists $struct->{Message}){
51 0         0 $message = $struct->{Message};
52             } else {
53 4         8 $message = "Unrecognized error message format";
54             }
55              
56 9 100       45 if (exists $headers->{'x-amzn-errortype'}){
    50          
    100          
57 2         10 $code = (split /:/, $headers->{'x-amzn-errortype'})[0];
58             } elsif (exists $struct->{Code}) {
59 0         0 $code = $struct->{Code};
60             } elsif (exists $struct->{ code }) {
61 2         4 $code = $struct->{ code };
62             } else {
63 5         12 $code = 'InvalidContent';
64             }
65 9   50     34 $request_id = $headers->{ 'x-amzn-requestid' } // '';
66              
67 9   50     212 Paws::Exception->new(
68             message => $message // '',
69             code => $code,
70             request_id => $request_id,
71             http_status => $http_status,
72             );
73             }
74              
75             sub handle_response_strtonativemap {
76 5     5 0 18 my ($self, $att_class, $value) = @_;
77              
78 5 50       17 if (not defined $value){
79 0         0 return $att_class->new(Map => {});
80             } else {
81 5         25 return $att_class->new(Map => $value);
82             }
83             }
84              
85             sub handle_response_strtoobjmap {
86 0     0 0 0 my ($self, $att_class, $value) = @_;
87              
88 0         0 my $inner_class = $att_class->meta->get_attribute('Map')->type_constraint->name;
89 0         0 ($inner_class) = ($inner_class =~ m/\[(.*)\]$/);
90 0         0 Paws->load_class("$inner_class");
91              
92 0 0       0 if (not defined $value){
93 0         0 return $att_class->new(Map => {});
94             } else {
95             return $att_class->new(Map => {
96 0         0 map { ($_ => $self->new_from_result_struct($inner_class, $value->{ $_ }) ) } keys %$value
  0         0  
97             });
98             }
99             }
100              
101             sub new_from_result_struct {
102 29     29 0 102 my ($self, $class, $result) = @_;
103 29         60 my %args;
104            
105 29 50       108 if ($class->does('Paws::API::StrToObjMapParser')) {
    50          
106 0         0 return $self->handle_response_strtoobjmap($class, $result);
107             } elsif ($class->does('Paws::API::StrToNativeMapParser')) {
108 0         0 return $self->handle_response_strtonativemap($class, $result);
109             } else {
110 29         10713 foreach my $att ($class->meta->get_attribute_list) {
111 148 50       27789 next if (not my $meta = $class->meta->get_attribute($att));
112              
113 148 100       2991 my $key = $meta->does('NameInRequest') ? $meta->request_name :
    50          
114             $meta->does('ParamInHeader') ? lc($meta->header_name) : $att;
115              
116 148         29039 my $att_type = $meta->type_constraint;
117              
118             # use Data::Dumper;
119             # print STDERR "USING KEY: $key\n";
120             # print STDERR "$att IS A '$att_type' TYPE\n";
121             # print STDERR "VALUE: " . Dumper($result);
122             # my $extracted_val = $result->{ $key };
123             # print STDERR "RESULT >>> $extracted_val\n";
124              
125             # We'll consider that an attribute without brackets [] isn't an array type
126 148 100       1118 if ($att_type !~ m/\[.*\]$/) {
    100          
127 136         3921 my $value = $result->{ $key };
128 136         220 my $value_ref = ref($value);
129              
130 136 100       251 if ($att_type =~ m/\:\:/) {
131             # Make the att_type stringify for module loading
132 25         740 Paws->load_class("$att_type");
133 25 100       69 if (defined $value) {
134 19 50       45 if (not $value_ref) {
135 0         0 $args{ $att } = $value;
136             } else {
137 19         468 my $att_class = $att_type->class;
138              
139 19 50       201 if ($att_class->does('Paws::API::StrToObjMapParser')) {
    100          
    50          
140 0         0 $args{ $att } = $self->handle_response_strtoobjmap($att_class, $value);
141             } elsif ($att_class->does('Paws::API::StrToNativeMapParser')) {
142 5         1985 $args{ $att } = $self->handle_response_strtonativemap($att_class, $value);
143             } elsif ($att_class->does('Paws::API::MapParser')) {
144 0         0 my $xml_keys = $att_class->xml_keys;
145 0         0 my $xml_values = $att_class->xml_values;
146              
147 0         0 $args{ $att } = $att_class->new(map { ($_->{ $xml_keys } => $_->{ $xml_values }) } @$value);
  0         0  
148             } else {
149 14         7758 $args{ $att } = $self->new_from_result_struct($att_class, $value);
150             }
151             }
152             }
153             } else {
154 111 100       3116 if (defined $value) {
155 89 100       194 if ($att_type eq 'Bool') {
156 24 100       678 if ($value eq 'true') {
    50          
    0          
157 12         161 $args{ $att } = 1;
158             } elsif ($value eq 'false') {
159 12         281 $args{ $att } = 0;
160             } elsif ($value == 1) {
161 0         0 $args{ $att } = 1;
162             } else {
163 0         0 $args{ $att } = 0;
164             }
165             } else {
166 65         1865 $args{ $att } = $value;
167             }
168             }
169             }
170             } elsif (my ($type) = ($att_type =~ m/^ArrayRef\[(.*)\]$/)) {
171 8         488 my $value = $result->{ $att };
172 8 50 66     40 $value = $result->{ $key } if (not defined $value and $key ne $att);
173 8         21 my $value_ref = ref($value);
174              
175 8 100       31 if ($type =~ m/\:\:/) {
176 6         29 Paws->load_class($type);
177              
178 6 50       43 if ($type->does('Paws::API::StrToObjMapParser')) {
    50          
    50          
179 0         0 $args{ $att } = [ map { $self->handle_response_strtoobjmap($type, $_) } @$value ];
  0         0  
180             } elsif ($type->does('Paws::API::StrToNativeMapParser')) {
181 0         0 $args{ $att } = [ map { $self->handle_response_strtonativemap($type, $_) } @$value ];
  0         0  
182             } elsif ($type->does('Paws::API::MapParser')) {
183 0         0 die "MapParser Type in an Array. Please implement me";
184             } else {
185 6         3520 $args{ $att } = [ map { $self->new_from_result_struct($type, $_) } @$value ];
  4         23  
186             }
187             } else {
188 2 50       8 if (defined $value){
189 0 0       0 if ($value_ref eq 'ARRAY') {
190 0         0 $args{ $att } = $value;
191             } else {
192 0         0 $args{ $att } = [ $value ];
193             }
194             }
195             }
196             }
197             }
198 29         4326 $class->new(%args);
199             }
200             }
201             1;