fix(gun): keep timeout-wrapped streams readable#847
Conversation
yordis
commented
Apr 22, 2026
- Timeout middleware moves request execution into a separate task, so Gun streamed responses need to keep headers readable there while leaving body chunks readable from the original caller.
- Stream read failures should surface as stream errors instead of crashing with a case clause mismatch.
- This preserves the Gun streaming path reported in Gun: streaming response body breaks with Tesla.Middleware.Timeout #709.
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
PR SummaryMedium Risk Overview
Reviewed by Cursor Bugbot for commit 97f1f12. Bugbot is set up for automated code reviews on this repo. Configure here. |
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
There was a problem hiding this comment.
Pull request overview
Fixes Gun streamed responses when used with Tesla.Middleware.Timeout by ensuring streamed body messages remain readable from the original caller process while request execution happens in a spawned timeout task, and by turning stream read failures into stream errors (instead of crashing on pattern mismatches).
Changes:
- Injects an adapter
:reply_tointo the request env inTimeoutso Gun can forward stream data back to the original caller. - Updates Gun adapter streaming to route
:gun_data/:gun_errormessages to the stream owner and handle stream errors explicitly. - Adds a regression test covering Gun streaming through the Timeout middleware.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
lib/tesla/middleware/timeout.ex |
Adds adapter :reply_to propagation from caller into the spawned timeout task. |
lib/tesla/adapter/gun.ex |
Routes streamed body messages to the intended owner and converts stream read failures into explicit stream errors. |
test/tesla/middleware/timeout_test.exs |
Adds regression coverage for Gun streaming + Timeout and updates stacktrace line assertions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 2d8f6bf. Configure here.
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
There was a problem hiding this comment.
Pull request overview
Fixes an interaction between Tesla.Middleware.Timeout (which executes requests in a separate task) and Tesla.Adapter.Gun streaming responses, preserving Gun’s streaming behavior reported in #709.
Changes:
- Add a regression test ensuring Gun
body_as: :streamremains readable when wrapped byTesla.Middleware.Timeout. - Pass the original caller pid through
env.privateso the Gun adapter can route stream body messages back to the caller while the timeout task reads the response headers. - Handle
{:error, reason}fromread_chunk/3in the streaming response path to avoid aCaseClauseErrorand raise a clearer stream error instead.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
test/tesla/middleware/timeout_test.exs |
Adds coverage for Gun streaming under Timeout and verifies adapter opts aren’t mutated. |
lib/tesla/middleware/timeout.ex |
Records the original caller pid in env.private for Gun streaming compatibility through the timeout task. |
lib/tesla/adapter/gun.ex |
Routes streamed body messages to the original caller and raises on stream read errors. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
There was a problem hiding this comment.
Pull request overview
Fixes Gun streamed responses when used with Tesla.Middleware.Timeout, ensuring response headers remain readable in the timeout task while streamed body chunks remain readable from the original caller process (per #709). It also ensures stream read failures are raised as stream errors rather than crashing with a CaseClauseError.
Changes:
- Add
:tesla_gun_stream_ownermetadata inTesla.Middleware.Timeoutto preserve the original caller as the stream consumer. - Update
Tesla.Adapter.Gunto route Gun messages appropriately across the timeout task boundary and to handle{:gun_error, pid, stream, reason}during streaming reads. - Expand test coverage for Gun streaming + timeout interactions and for preserving adapter opts.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
lib/tesla/middleware/timeout.ex |
Stores original caller pid in env.private for Gun streaming handoff across the timeout task. |
lib/tesla/adapter/gun.ex |
Wraps/routers Gun reply_to for streamed/chunked responses and converts stream read failures into stream errors. |
test/tesla/middleware/timeout_test.exs |
Adds regression tests for Gun streaming through the Timeout middleware and verifies adapter opts aren’t mutated. |
test/tesla/adapter/gun_test.exs |
Adds tests ensuring explicit reply_to behavior is preserved, including when stream ownership is handed off. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
