99use AsyncAws \Core \Exception \Http \NetworkException ;
1010use AsyncAws \Core \Exception \Http \RedirectionException ;
1111use AsyncAws \Core \Exception \Http \ServerException ;
12+ use AsyncAws \Core \Exception \RuntimeException ;
1213use Symfony \Contracts \HttpClient \Exception \TransportExceptionInterface ;
1314use Symfony \Contracts \HttpClient \HttpClientInterface ;
1415use Symfony \Contracts \HttpClient \ResponseInterface ;
@@ -42,17 +43,16 @@ class Result
4243 private $ prefetchResults = [];
4344
4445 /**
45- * @var HttpClientInterface
46+ * @var HttpClientInterface|null
4647 */
4748 private $ httpClient ;
4849
4950 /**
50- * A Result can be resolved many times. This boolean is true if the result
51- * has been resolved at least once.
51+ * A Result can be resolved many times. This variable contains the last resolve result.
5252 *
53- * @var bool
53+ * @var bool|NetworkException|HttpException|null
5454 */
55- private $ isResolved = false ;
55+ private $ resolveResult ;
5656
5757 public function __construct (ResponseInterface $ response , HttpClientInterface $ httpClient , AbstractApi $ awsClient = null , $ request = null )
5858 {
@@ -68,7 +68,7 @@ public function __destruct()
6868 array_shift ($ this ->prefetchResponses )->cancel ();
6969 }
7070
71- if (false === $ this ->isResolved ) {
71+ if (null === $ this ->resolveResult ) {
7272 $ this ->resolve ();
7373 }
7474 }
@@ -85,36 +85,50 @@ public function __destruct()
8585 */
8686 final public function resolve (?float $ timeout = null ): bool
8787 {
88- if (!isset ($ this ->response )) {
88+ if (null !== $ this ->resolveResult ) {
89+ if ($ this ->resolveResult instanceof \Exception) {
90+ throw $ this ->resolveResult ;
91+ }
92+
93+ if (\is_bool ($ this ->resolveResult )) {
94+ return $ this ->resolveResult ;
95+ }
96+
97+ throw new RuntimeException ('Unexpected resolve state ' );
98+ }
99+
100+ if (null === $ this ->response || null === $ this ->httpClient ) {
89101 return true ;
90102 }
91103
92104 try {
93- if (null !== $ timeout && $ this ->httpClient ->stream ($ this ->response , $ timeout )->current ()->isTimeout ()) {
94- return false ;
105+ foreach ($ this ->httpClient ->stream ($ this ->response , $ timeout ) as $ chunk ) {
106+ if ($ chunk ->isTimeout ()) {
107+ return false ;
108+ }
109+ if ($ chunk ->isFirst ()) {
110+ break ;
111+ }
95112 }
113+
96114 $ statusCode = $ this ->response ->getStatusCode ();
97115 } catch (TransportExceptionInterface $ e ) {
98- // When a network error occurs
99- $ this ->isResolved = true ;
100-
101- throw new NetworkException ('Could not contact remote server. ' , 0 , $ e );
116+ throw $ this ->resolveResult = new NetworkException ('Could not contact remote server. ' , 0 , $ e );
102117 }
103118
104- $ this ->isResolved = true ;
105119 if (500 <= $ statusCode ) {
106- throw new ServerException ($ this ->response );
120+ throw $ this -> resolveResult = new ServerException ($ this ->response );
107121 }
108122
109123 if (400 <= $ statusCode ) {
110- throw new ClientException ($ this ->response );
124+ throw $ this -> resolveResult = new ClientException ($ this ->response );
111125 }
112126
113127 if (300 <= $ statusCode ) {
114- throw new RedirectionException ($ this ->response );
128+ throw $ this -> resolveResult = new RedirectionException ($ this ->response );
115129 }
116130
117- return true ;
131+ return $ this -> resolveResult = true ;
118132 }
119133
120134 /**
@@ -128,50 +142,50 @@ final public function resolve(?float $timeout = null): bool
128142 */
129143 final public function info (): array
130144 {
131- if (! isset ( $ this ->response ) ) {
145+ if (null === $ this ->response ) {
132146 return [
133- 'resolved ' => $ this ->isResolved ,
147+ 'resolved ' => null !== $ this ->resolveResult ,
134148 ];
135149 }
136150
137151 return [
138- 'resolved ' => $ this ->isResolved ,
152+ 'resolved ' => null !== $ this ->resolveResult ,
139153 'response ' => $ this ->response ,
140154 'status ' => (int ) $ this ->response ->getInfo ('http_code ' ),
141155 ];
142156 }
143157
144158 final public function cancel (): void
145159 {
146- if (! isset ( $ this ->response ) ) {
160+ if (null === $ this ->response ) {
147161 return ;
148162 }
149163
150164 $ this ->response ->cancel ();
151- unset($ this ->response );
165+ $ this ->resolveResult = false ;
166+ $ this ->response = null ;
152167 }
153168
154169 final protected function registerPrefetch (self $ result ): void
155170 {
156- $ this ->prefetchResults [spl_object_hash ($ result )] = $ result ;
171+ $ this ->prefetchResults [spl_object_id ($ result )] = $ result ;
157172 }
158173
159174 final protected function unregisterPrefetch (self $ result ): void
160175 {
161- unset($ this ->prefetchResults [spl_object_hash ($ result )]);
176+ unset($ this ->prefetchResults [spl_object_id ($ result )]);
162177 }
163178
164179 final protected function initialize (): void
165180 {
166- if (! isset ( $ this ->response ) ) {
181+ if (null === $ this ->response || null === $ this -> httpClient ) {
167182 return ;
168183 }
184+
169185 $ this ->resolve ();
170186 $ this ->populateResult ($ this ->response , $ this ->httpClient );
171- unset($ this ->response );
172- if (isset ($ this ->httpClient )) {
173- unset($ this ->httpClient );
174- }
187+ $ this ->response = null ;
188+ $ this ->httpClient = null ;
175189 }
176190
177191 protected function populateResult (ResponseInterface $ response , HttpClientInterface $ httpClient ): void
0 commit comments