Skip to content

test(bedrock): lock in legible non-JSON gateway error surfacing (PC-4775)#98

Open
cotovanu-cristian wants to merge 1 commit into
mainfrom
fix/pc-4775-bedrock-nonjson-body
Open

test(bedrock): lock in legible non-JSON gateway error surfacing (PC-4775)#98
cotovanu-cristian wants to merge 1 commit into
mainfrom
fix/pc-4775-bedrock-nonjson-body

Conversation

@cotovanu-cristian

Copy link
Copy Markdown
Collaborator

Summary

No production code change. This PR adds the regression coverage that PC-4775 needs — it locks in the legible-error behavior for a non-2xx HTML / non-JSON gateway body, on both converse and converse_stream.

The core fix already landed in #95 ("fix(bedrock): raise_for_status in WrappedBotoClient so gateway errors surface", merged 2026-06-23), which added response.raise_for_status() before .json(). That commit post-dates the PC-4775 failing job (runtime 195.1.0), which is why the job hit the old unconditional .json() and crashed with an opaque json.decoder.JSONDecodeError.

Why this PR exists

#95's tests only exercised a plain httpx.Client with a JSON error body and asserted a bare httpx.HTTPStatusError. They did not cover the actual PC-4775 scenario:

  • a non-2xx HTML body (the incident was 403 <!DOCTYPE html>), and
  • routed through the patch_raise_for_status-wrapped client that production uses (UiPathHttpxClient).

So a regression of the legible-error behavior would have gone uncaught.

What the tests guard

Through the patched client, a 403 HTML body now surfaces as a typed UiPathPermissionDeniedError (a UiPathAPIError) carrying:

  • status_code == 403, and
  • the HTML body excerpt (error.body),

instead of an opaque JSONDecodeError (converse) or botocore.eventstream.ChecksumMismatch (streaming).

Mutation-verified: removing the raise_for_status() guards from utils.py makes both new tests fail (converse → no raise; stream → ChecksumMismatch), confirming they genuinely lock in the fix. With the guards intact, all 8 tests in the file pass.

Validation

  • uv run ruff check — pass
  • uv run ruff format --check — pass
  • uv run pyright tests/.../test_wrapped_boto_client.py — 0 errors
  • uv run pytest tests/.../test_wrapped_boto_client.py — 8 passed
    • (pre-existing, unrelated client_settings fixture errors in test_unit.py/test_integration.py reproduce on clean main and require UiPath env; not touched here.)

Related

🤖 Generated with Claude Code

…775)

The core fix already landed in #95 (raise_for_status before .json() on the
converse and streaming paths, 2026-06-23), which post-dates the PC-4775 failing
job's runtime 195.1.0. No production code changes here.

#95's tests only exercised a plain httpx.Client with a JSON error body and
asserted a bare httpx.HTTPStatusError. They did not cover the actual incident:
a non-2xx HTML / non-JSON body through the patch_raise_for_status-wrapped client
that production uses. Without the guard, that body crashed converse with a
JSONDecodeError and the streaming path with a botocore ChecksumMismatch.

Add regression tests that drive converse and converse_stream through a patched
client returning a 403 HTML body, asserting a typed UiPathPermissionDeniedError
carrying status 403 and the body excerpt instead of an opaque error. A mutation
check (removing the raise_for_status guards) confirms both tests fail.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant