Skip to content

Commit 4e27430

Browse files
committed
Close request when initial response fails and propogate error
1 parent 7c72f8f commit 4e27430

File tree

2 files changed

+27
-9
lines changed
  • codegen/core/src/main/java/software/amazon/smithy/python/codegen
  • packages/smithy-http/src/smithy_http/aio

2 files changed

+27
-9
lines changed

codegen/core/src/main/java/software/amazon/smithy/python/codegen/ClientGenerator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,9 +286,9 @@ def _classify_error(
286286
request_future, response_future,
287287
)
288288
except Exception as e:
289-
if request_future is not None and not request_future.done:
289+
if request_future is not None and not request_future.done():
290290
request_future.set_exception($4T(e))
291-
if response_future is not None and not response_future.done:
291+
if response_future is not None and not response_future.done():
292292
response_future.set_exception($4T(e))
293293
294294
# Make sure every exception that we throw is an instance of $4T so

packages/smithy-http/src/smithy_http/aio/crt.py

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,15 @@ def on_response(
174174
kind=FieldPosition.HEADER,
175175
)
176176

177-
self._response_future.set_result(
178-
AWSCRTHTTPResponse(
179-
status=status_code,
180-
fields=fields,
181-
body=self._body,
182-
)
177+
response = AWSCRTHTTPResponse(
178+
status=status_code,
179+
fields=fields,
180+
body=self._body,
183181
)
182+
if status_code != 200 and status_code >= 300:
183+
self._response_future.set_exception(CRTErrorResponse(response))
184+
else:
185+
self._response_future.set_result(response)
184186

185187
async def await_response(self) -> AWSCRTHTTPResponse:
186188
return await asyncio.wrap_future(self._response_future)
@@ -193,6 +195,18 @@ def _cancel(self, completion_future: ConcurrentFuture[int | Exception]) -> None:
193195
self._response_future.cancel()
194196

195197

198+
class CRTErrorResponse(Exception):
199+
def __init__(self, response: AWSCRTHTTPResponse) -> None:
200+
self._status = response.status
201+
self._response = response
202+
203+
super().__init__(f"Request failed with status code {self._status}")
204+
205+
@property
206+
def response(self) -> AWSCRTHTTPResponse:
207+
return self._response
208+
209+
196210
ConnectionPoolKey = tuple[str, str, int | None]
197211
ConnectionPoolDict = dict[ConnectionPoolKey, "crt_http.HttpClientConnection"]
198212

@@ -251,7 +265,11 @@ async def send(
251265
crt_stream.completion_future.add_done_callback(
252266
partial(self._close_input_body, body=crt_body)
253267
)
254-
return await response_factory.await_response()
268+
try:
269+
return await response_factory.await_response()
270+
except CRTErrorResponse as e:
271+
await close(crt_body)
272+
return e.response
255273

256274
def _close_input_body(
257275
self, future: ConcurrentFuture[int], *, body: "BufferableByteStream | BytesIO"

0 commit comments

Comments
 (0)