Skip to content

Guzzle request options cause HTTP error responses to bypass ResponseUtil #265

Description

@superdav42

Summary

When HttpTransporter has non-null RequestOptions and discovers a Guzzle-shaped client, it calls Guzzle's send() method with translated options. The options currently omit http_errors => false, so Guzzle can throw for 4xx/5xx responses before the response reaches ResponseUtil::throwIfNotSuccessful().

This leaves callers with the generic wrapper message HTTP client error occurred while sending request ... instead of the SDK's typed ClientException or ServerException.

Evidence

The request-options path originated in #99 and PR #109. This report is specifically about preserving PSR-18-style response semantics on that Guzzle-specific options path.

Expected behavior

Guzzle-backed requests with RequestOptions should return HTTP error responses to the SDK. Provider code can then pass those responses to ResponseUtil, which throws the appropriate typed SDK exception. Network and transport failures should continue to use the existing exception path.

Proposed implementation

Files to modify

  • src/Providers/Http/HttpTransporter.php — pass http_errors => false in the Guzzle options produced by buildGuzzleOptions().
  • tests/unit/Providers/Http/HttpTransporterTest.php — add regression coverage for the option and an HTTP error response.
  • tests/mocks/GuzzleLikeClient.php — only if needed to model Guzzle's status-error behavior in the focused test.

Complete write surface

  • Callers/readers: HttpTransporter::send(), sendWithGuzzle(), and providers that subsequently call ResponseUtil::throwIfNotSuccessful().
  • Mutation path: HttpTransporter::buildGuzzleOptions() is the single Guzzle option translation path.
  • Tests/fixtures: HttpTransporterTest and GuzzleLikeClient; ResponseUtilTest already covers typed status translation independently.
  • Schemas/config/generated artifacts: none found; this changes an internal Guzzle option only.

Compatibility and hazards

  • Apply http_errors only to the Guzzle-shaped send() path; ClientWithOptionsInterface and ordinary PSR-18 sendRequest() paths should remain unchanged.
  • Disabling Guzzle status exceptions aligns this path with PSR-18 semantics, where 4xx/5xx responses are returned rather than treated as transport failures.
  • Do not add automatic retry behavior in this change.
  • Preserve timeout, connect-timeout, redirect, and network-exception behavior.

Acceptance criteria

  • A Guzzle-shaped client called with non-null RequestOptions receives http_errors => false.
  • A simulated 529 response is returned by HttpTransporter and can be translated by ResponseUtil into ServerException with code 529 and the Overloaded message.
  • A representative 4xx response no longer takes the generic HTTP client error occurred path.
  • Existing timeout, redirect, successful-response, and network-exception tests continue to pass.

Verification

vendor/bin/phpunit tests/unit/Providers/Http/HttpTransporterTest.php
vendor/bin/phpunit tests/unit/Providers/Http/Util/ResponseUtilTest.php
composer lint

AI disclosure

This issue was investigated and drafted interactive OpenCode session.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Needs DevIssues needing development[Type] BugAn existing feature does not function as intendedorigin:interactiveCreated by interactive user sessionstatus:in-reviewPR open, awaiting review/merge

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions