aws-samples / aws-samples/sample-bedrock-proxy-gateway

Streaming error handler raises httpx.ResponseNotRead, masking the real error

Open
#54 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
12
Forks
0
PR merge metrics
No merged PRs in 30d

Description

## Context

On the streaming endpoints, the error handler reads `e.response.text` after `raise_for_status()` on a response opened with `client.stream(...)`. A streamed body isn't read automatically, so accessing `.text` raises `httpx.ResponseNotRead`. The handler itself throws, and the real upstream error is lost.

Specifically, the error reads:
_**httpx.ResponseNotRead: Attempted to access streaming response content, without having called `read()`.**_

Moving `await e.response.aread()` into the `except` block doesn't help either: by then the `async with client.stream(...)` context has closed the stream, raising `httpx.StreamClosed`.

## Affected code

1) `bedrock_routes.py`- the `except httpx.HTTPStatusError` branches in the `converse-stream` and `invoke-with-response-stream` generators read `e.response.text`, but the body was never read (`raise_for_status()` fires before any `aiter_bytes()`).

2) `bedrock_service_httpx.py` - same pattern in the STS handler (`e.response.text[:200]` on a non-OK streamed response).

## Suggested fix

1) In `bedrock_routes.py`, check the status and read the body **inside** the `async with` block (before it closes): replace `raise_for_status()` + the `HTTPStatusError` branch with an explicit `if resp.status_code >= 400: await resp.aread()` then surface `resp.text`.
2) In `bedrock_service_httpx.py`, add `await e.response.aread()` before reading `e.response.text`.

Note: Reproducible with a local server returning 403 on a streaming POST. In this scenario, `e.response.text` raises `httpx.ResponseNotRead`; reading inside the `async with` returns the body.

Contributor guide

Open the contributing guide

Research direction

Start in bedrock_routes.py at the converse-stream and invoke-with-response-stream error branches, then inspect the matching STS handler in bedrock_service_httpx.py. Reproduce the failure with a local server returning 403 for a streaming POST and trace response lifetime inside async with. Done means the upstream error body is surfaced without ResponseNotRead or StreamClosed masking it.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.