Skip to content

Map HTTP/2 body INTERNAL_ERROR to RemoteError - #236

Closed
samuel-williams-shopify wants to merge 2 commits into
mainfrom
map-http2-body-remote-error
Closed

samuel-williams-shopify wants to merge 2 commits into
mainfrom
map-http2-body-remote-error

Conversation

@samuel-williams-shopify

Copy link
Copy Markdown
Contributor

Summary

  • map an HTTP/2 stream INTERNAL_ERROR raised while reading a response body to Protocol::HTTP::RemoteError
  • preserve the original Protocol::HTTP2::StreamError as the implicit exception cause
  • add coverage for the headers-then-reset ordering reported in the issue

This complements the pre-response mapping added in #232. Once response headers have resolved readiness, a later reset surfaces from the body and cannot safely be retried inside Async::HTTP::Client. Normalizing it as RemoteError lets integrations apply their own retry policy.

Testing

  • focused HTTP/2 regression: 4 tests, 20 assertions
  • RuboCop: 128 files, no offenses
  • full suite: 243 passed, 3 skipped; one unrelated live-network test errored and reproduced independently as ECONNRESET during SSL_connect

Fixes #231

@jakeonfire

Copy link
Copy Markdown

any blockers to merging this?

@ioquatix

Copy link
Copy Markdown
Member

No, let me do a final pass over these changes.

@samuel-williams-shopify

Copy link
Copy Markdown
Contributor Author

After the final review, we're closing this PR and addressing the Faraday integration directly in socketry/async-http-faraday#61.

This PR normalizes one known body-read failure, but it does not establish a useful general retry contract. Body#read is an extensible interface: protocol, transport, decompression, producer, and application exceptions can all propagate from it. Wrapping HTTP/2 INTERNAL_ERROR in RemoteError does not tell the caller whether it can safely repeat the request or discard a partially consumed response.

The benefit here is consistency with the existing pre-response RemoteError mapping. We decided that benefit does not justify adding another wrapper solely to enable Faraday's error handling. The concrete problem reported in #231 is that a StreamError during body consumption bypasses the adapter's Faraday::ConnectionFailed translation. The adapter can translate that exception directly, preserving it as the cause, and leave retry policy to the application or its configured middleware.

The companion PR will retain support for the already-released RemoteError behavior, handle HTTP/2 StreamError directly, and clarify that retries require a safely repeatable request, a replayable request body, and the ability to discard partial response output. It will also explain how Faraday retries can compound async-http's internal attempts.

This closes the proposed abstraction change, not the original bug report: #231 remains open while the Faraday fix is completed. Thanks for the detailed traces and review, and sorry for the delay in reaching this decision.

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.

HTTP/2: server RST_STREAM with INTERNAL_ERROR isn't covered by the existing retry mechanism

3 participants