File Coverage

blib/lib/Paws/Net/JsonResponse.pm
Criterion Covered Total %
statement 99 115 86.0
branch 59 76 77.6
condition 3 3 100.0
subroutine 10 10 100.0
pod 0 6 0.0
total 171 210 81.4


line stmt bran cond sub pod time code
1             package Paws::Net::JsonResponse;
2 13     13   8181 use Moose::Role;
  13         36  
  13         106  
3 13     13   72211 use JSON::MaybeXS;
  13         93  
  13         860  
4 13     13   85 use Carp qw(croak);
  13         32  
  13         756  
5 13     13   84 use Paws::Exception;
  13         116  
  13         14861  
6            
7             sub handle_response {
8 80     80 0 81479 my ($self, $call_object, $http_status, $content, $headers) = @_;
9              
10 80 100       416 if (defined $headers->{ 'x-amz-crc32' }) {
11 3         1924 require String::CRC32;
12 3         2138 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 3 50       25 ) if ($crc != $headers->{ 'x-amz-crc32' });
18             }
19              
20 80 100       357 if ( $http_status >= 300 ) {
21 26         111 return $self->error_to_exception($call_object, $http_status, $content, $headers);
22             } else {
23 54         368 return $self->response_to_object($call_object, $http_status, $content, $headers);
24             }
25             }
26            
27             sub unserialize_response {
28 72     72 0 252 my ($self, $data) = @_;
29              
30 72         1258 return decode_json( $data );
31             }
32              
33             sub error_to_exception {
34 26     26 0 91 my ($self, $call_object, $http_status, $content, $headers) = @_;
35            
36 26         74 my $struct = eval { $self->unserialize_response( $content ) };
  26         101  
37 26 100       102 if ($@) {
38 12         217 return Paws::Exception->new(
39             message => $@,
40             code => 'InvalidContent',
41             request_id => '', #$request_id,
42             http_status => $http_status,
43             );
44             }
45              
46 14         42 my ($message, $request_id);
47              
48 14 100       62 if (exists $struct->{message}){
    50          
49 12         31 $message = $struct->{message};
50             } elsif (exists $struct->{Message}){
51 0         0 $message = $struct->{Message};
52             } else {
53             # Rationale for this condition is in Issue #82
54 2 50       12 if ($struct->{__type} eq 'InternalError'){
55 2         8 $message = '';
56             } else {
57 0         0 Moose->throw_error("Unrecognized error message format");
58             }
59             }
60              
61 14         36 my $code = $struct->{__type};
62 14 100       67 if ($code =~ m/#/) {
63 2         12 $code = (split /#/, $code)[1];
64             }
65 14         41 $request_id = $headers->{ 'x-amzn-requestid' };
66              
67 14         394 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 4     4 0 17 my ($self, $att_class, $value) = @_;
77              
78 4 50       16 if (not defined $value){
79 0         0 return $att_class->new(Map => {});
80             } else {
81 4         29 return $att_class->new(Map => $value);
82             }
83             }
84              
85             sub handle_response_strtoobjmap {
86 9     9 0 35 my ($self, $att_class, $value) = @_;
87              
88 9         22 my $is_array = 0;
89 9         24 my $inner_class;
90 9         58 my $class = $att_class->meta->get_attribute('Map')->type_constraint->name;
91              
92 9 100       871 if (my ($array_type) = ($class =~ m/^HashRef\[ArrayRef\[(.*)\]\]$/)){
    50          
93 3         10 $inner_class = $array_type;
94 3         8 $is_array = 1;
95             } elsif (my ($inner_type) = ($class =~ m/^HashRef\[(.*)\]$/)) {
96 6         23 $inner_class = $inner_type;
97 6         16 $is_array = 0;
98             }
99              
100 9         57 Paws->load_class("$inner_class");
101              
102 9 100       38 if ($is_array) {
103 3 50       15 if (not defined $value){
104 0         0 return $att_class->new(Map => {});
105             } else {
106             return $att_class->new(Map => {
107 3         16 map { my $k = $_; ($k => [ map { $self->new_from_result_struct($inner_class, $_) } @{ $value->{ $k } } ] ) } keys %$value
  3         10  
  3         8  
  4         2304  
  3         9  
108             });
109             }
110             } else {
111 6 50       28 if (not defined $value){
112 0         0 return $att_class->new(Map => {});
113             } else {
114             return $att_class->new(Map => {
115 6         40 map { ($_ => $self->new_from_result_struct($inner_class, $value->{ $_ }) ) } keys %$value
  9         7121  
116             });
117             }
118             }
119             }
120              
121             sub new_from_result_struct {
122 112     112 0 514 my ($self, $class, $result) = @_;
123 112         250 my %args;
124            
125 112 100       582 if ($class->does('Paws::API::StrToObjMapParser')) {
    50          
126 2         479 return $self->handle_response_strtoobjmap($class, $result);
127             } elsif ($class->does('Paws::API::StrToNativeMapParser')) {
128 0         0 return $self->handle_response_strtonativemap($class, $result);
129             } else {
130 110         53455 foreach my $att ($class->meta->get_attribute_list) {
131 637 50       80215 next if (not my $meta = $class->meta->get_attribute($att));
132              
133 637 50       18533 my $key = $meta->does('NameInRequest') ? $meta->request_name :
    100          
134             $meta->does('ParamInHeader') ? lc($meta->header_name) : $att;
135              
136 637         133568 my $att_type = $meta->type_constraint;
137              
138             # use Data::Dumper;
139             # print STDERR "USING KEY: $key\n";
140             # print STDERR "$att IS A '$att_type' TYPE\n";
141             # print STDERR "VALUE: " . Dumper($result);
142             # my $extracted_val = $result->{ $key };
143             # print STDERR "RESULT >>> $extracted_val\n";
144              
145             # We'll consider that an attribute without brackets [] isn't an array type
146 637 100       7052 if ($att_type !~ m/\[.*\]$/) {
    100          
147 498         17610 my $value = $result->{ $key };
148 498         1082 my $value_ref = ref($value);
149              
150 498 100       1369 if ($att_type =~ m/\:\:/) {
151             # Make the att_type stringify for module loading
152 101         3615 Paws->load_class("$att_type");
153 101 100       461 if (defined $value) {
154 29 50       120 if (not $value_ref) {
155 0         0 $args{ $att } = $value;
156             } else {
157 29         926 my $att_class = $att_type->class;
158              
159 29 100       489 if ($att_class->does('Paws::API::StrToObjMapParser')) {
    100          
    50          
160 6         1410 $args{ $att } = $self->handle_response_strtoobjmap($att_class, $value);
161             } elsif ($att_class->does('Paws::API::StrToNativeMapParser')) {
162 4         2147 $args{ $att } = $self->handle_response_strtonativemap($att_class, $value);
163             } elsif ($att_class->does('Paws::API::MapParser')) {
164 0         0 my $xml_keys = $att_class->xml_keys;
165 0         0 my $xml_values = $att_class->xml_values;
166              
167 0         0 $args{ $att } = $att_class->new(map { ($_->{ $xml_keys } => $_->{ $xml_values }) } @$value);
  0         0  
168             } else {
169 19         13323 $args{ $att } = $self->new_from_result_struct($att_class, $value);
170             }
171             }
172             }
173             } else {
174 397 100       13546 if (defined $value) {
175 234 100       750 if ($att_type eq 'Bool') {
176 9 100       439 if ($value eq 'true') {
    50          
    0          
177 8         191 $args{ $att } = 1;
178             } elsif ($value eq 'false') {
179 1         42 $args{ $att } = 0;
180             } elsif ($value == 1) {
181 0         0 $args{ $att } = 1;
182             } else {
183 0         0 $args{ $att } = 0;
184             }
185             } else {
186 225         7756 $args{ $att } = $value;
187             }
188             }
189             }
190             } elsif (my ($type) = ($att_type =~ m/^ArrayRef\[(.*)\]$/)) {
191 107         7622 my $value = $result->{ $att };
192 107 100 100     740 $value = $result->{ $key } if (not defined $value and $key ne $att);
193 107         250 my $value_ref = ref($value);
194              
195 107 100       393 if ($type =~ m/\:\:/) {
196 63         314 Paws->load_class($type);
197              
198 63 100       491 if ($type->does('Paws::API::StrToObjMapParser')) {
    50          
    50          
199 2         461 $args{ $att } = [ map { $self->handle_response_strtoobjmap($type, $_) } @$value ];
  1         6  
200             } elsif ($type->does('Paws::API::StrToNativeMapParser')) {
201 0         0 $args{ $att } = [ map { $self->handle_response_strtonativemap($type, $_) } @$value ];
  0         0  
202             } elsif ($type->does('Paws::API::MapParser')) {
203 0         0 die "MapParser Type in an Array. Please implement me";
204             } else {
205 61         43243 $args{ $att } = [ map { $self->new_from_result_struct($type, $_) } @$value ];
  34         21267  
206             }
207             } else {
208 44 100       174 if (defined $value){
209 5         22 $args{ $att } = $value;
210             }
211             }
212             }
213             }
214 110         11228 $class->new(%args);
215             }
216             }
217             1;