Map socket writer exceptions and rejections to SocketError - #6987
Conversation
🦋 Changeset detectedLatest commit: 90c942a The changes in this PR will be included in the next version bump. This PR includes changesets to release 30 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
ℹ️ No critical issues — the added regression test correctly reproduces the defect, but the specification could be tightened and expanded before the implementation fix lands.
Reviewed changes
Reviewed the single-file diff against fab7668. It adds one focused test in packages/platform-node/test/NodeSocket.test.ts that expects a WritableStream write rejection from Socket.fromTransformStream to be surfaced as a SocketError failure rather than a defect.
- The new test currently fails as intended: the output is
Die(Error: write failed)instead ofFail(SocketError). - The test only covers the
fromTransformStreampath; the PR title and description also call out the WebSocketsendpath, which is not yet covered. - The assertion validates
Socket.SocketError.is(reason.error)but does not enforce that the reason is aSocketWriteError, which is the convention used by the platform socket adapters (NodeSocket,DenoSocket).
ℹ️ WebSocket writer path is not covered by the new regression
The PR title and description highlight both fromTransformStream writable rejections and synchronous WebSocket#send exceptions. The current diff only adds a test for the transform-stream side. Before the implementation fix is added, consider adding a matching test for the WebSocket writer so both paths are pinned. This can be done by providing a WebSocketConstructor that returns a subclass of the mock WebSocket whose send method throws synchronously.
ℹ️ Nitpicks
- The transform-stream test name is accurate, but the PR title suggests broader scope; either expand the test or adjust the title when the implementation lands.
@v0 or keep the SHA fresh with Dependabot | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏
| } | ||
| })) | ||
| latch.whenOpen( | ||
| Effect.try({ |
There was a problem hiding this comment.
Let's use Effect.suspend and normal try / catch instead
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
Reviewed the delta since the prior pullfrog review (fab7668): the implementation fix has landed and the prior feedback has been addressed.
packages/effect/src/unstable/socket/Socket.tsnow maps both writer failure paths toSocketErrorwith aSocketWriteErrorreason: synchronousWebSocket#sendexceptions via atry/catchinfromWebSocket, and writable-stream write rejections viaEffect.tryPromiseinfromTransformStream.packages/platform-node/test/NodeSocket.test.tsgained a regression test for the WebSocketsend-throws path and both tests now assert that the error reason is specificallySocketWriteError, matching the convention used byNodeSocketandDenoSocket..changeset/soft-sockets-write.mdadds a concise patch changeset foreffect.
Focused tests pass and pnpm lint-fix is clean. Prior Pullfrog review threads have been resolved.
@v0 or keep the SHA fresh with Dependabot | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏
Bundle Size AnalysisGenerated from PR build output; treat the content below as untrusted.
|

Summary
Transform-stream write rejection and synchronous WebSocket send errors become defects rather than typed SocketError failures, bypassing the recovery promised by Socket.writer.
Important
This PR starts with focused failing reproduction tests. Add the implementation fix to this same branch; CI is expected to fail until that fix is included.
Socket writer failures escape as defects
Module:
SocketAudit ID:
unstable-http-socket-writer-defectsSeverity / confidence: medium / high
What happens
Transform-stream write rejection and synchronous WebSocket send errors become defects rather than typed SocketError failures, bypassing the recovery promised by Socket.writer.
Why it happens
The WebSocket writer wraps send in Effect.sync, making synchronous exceptions defects, and the transform-stream writer uses Effect.promise, making rejected WritableStream.write promises defects.
Expected behavior
Socket.writer returns effects whose declared failure channel is SocketError.
Relevant implementation
These links and excerpts are pinned to audit base
c9b56ab507f224426ee8388dc450da447ec4715f.packages/effect/src/unstable/socket/Socket.ts:738-746packages/effect/src/unstable/socket/Socket.ts:898-910View problematic code at
packages/effect/src/unstable/socket/Socket.ts:738-746View exact lines on GitHub
View problematic code at
packages/effect/src/unstable/socket/Socket.ts:898-910View exact lines on GitHub
Reproduction
pnpm test --run packages/platform-node/test/NodeSocket.test.tsObserved failure: Failed as intended because the transform-stream write rejection produced Die(Error: write failed), not Fail(SocketError).
Implementation handoff
The initial reproduction tests on this branch are the regression specification for the implementation fix that should follow in this PR.
pnpm test --run packages/platform-node/test/NodeSocket.test.tsAudit provenance
c9b56ab507f224426ee8388dc450da447ec4715fc9b56ab507f224426ee8388dc450da447ec4715funstable-http-socket-writer-defectsCloses EFF-424