fix(webfetch): handle bodies without dump - #8
Conversation
|
CI is currently marked |
code-yeongyu
left a comment
There was a problem hiding this comment.
Verdict
REQUEST_CHANGES. The body-disposal implementation is directionally correct and passes the local Bun and Node/Vitest suites, but the explicit-article regression test no longer proves the behavior named by the test. That is a blocking test gap because the regression can re-enter production unnoticed.
Blockers
test/webfetch-explicit-article.test.ts:3-33- The changed test is no longer capable of failing whenReadability.parse()is called. The mock'sparse()throws anError, butextractReadableArticle()catchesErrorand returnsundefined;htmlToMarkdown()then falls back to Turndown on the original HTML, which still contains both strings asserted by the test. Thus the test passes despite the exact regression it claims to cover. Restore a direct call-count assertion, or make an accidental parse throw a runner-compatible non-Errorsentinel that propagates, while retaining the output assertions.
Non-blocking notes
-
src/webfetch/fetcher.ts:48-52,212-233- The optionaldump?()contract is feature-detected before calling it, anddestroyDiscardedBody()is used both whendumpis absent and whendumprejects with anError. No other call site assumesdumpexists. Rethrowing non-Errordump failures preserves the previous behavior and avoids swallowing arbitrary thrown values. In Undici 7.28.0,destroy()anddestroy(error)both abort an active, undrained body/socket; the changed call primarily changes the emitted error identity, not reuse semantics for this discard path. -
src/webfetch/fetcher.ts:229-233- The one-shot error listener is appropriate for the deliberate no-consumer teardown and does not mask a normal consumer mid-read, since it is only installed bydiscardBody(). If the helper is ever called repeatedly on the same already normally-closed body, however,once("error", noop)can remain attached because no error will be emitted anddestroy()is a no-op; adestroyed/closed guard or listener cleanup would avoid that latent leak. This is not currently reachable through the production call graph, which discards each response body once. -
src/webfetch/fetcher.test.ts:43-56andtest/webfetch.test.ts:566-591- The new tests are real integration tests rather than mocks asserting mock calls. Under Bun, the actual Undici body has nodump(), so the redirect test and the new fetcher test exercise the no-dumpbranch; under Node, the same redirect test exercises boundeddump()draining. The redirect test therefore does reachdiscardBody(), but it does not directly assert that the discarded stream was closed or that the connection was reusable. -
The new
src/webfetch/fetcher.test.tsis included bybun testbut excluded by the Vitest config (test/**/*.test.ts), so the Bun-specific no-dumpregression is not covered by the repository's Node CI workflow. This is a coverage/CI note rather than an implementation failure. Local results: Bun 1.4.0 reported 42 passed, 0 failed;npx vitest --runon Node v26.7.0 reported 41 passed, 0 failed; typecheck and Biome were clean. -
The cubic check is NEUTRAL because its review quota was exhausted; it provided no code findings to evaluate. The GitHub CI workflow is also awaiting maintainer approval for this fork-origin run, which is unrelated to the patch.
code-yeongyu
left a comment
There was a problem hiding this comment.
Verdict
APPROVE. The round-1 blocker is resolved: the explicit-article regression test now asserts the Readability parse call count, so it fails when the fallback runs. The local mutation check failed under both Bun and Vitest, and the restored implementation passed under both.
Blockers
None.
Non-blocking notes
- The fix commit 313d476 touches only
test/webfetch-explicit-article.test.ts; no unrelated or source changes were introduced by that commit. - Full gates passed:
bun test42 passed / 0 failed;npx vitest --run41 passed / 0 failed;npm run typecheckpassed;npx biome check .passed with no fixes.
|
Merging with admin override on the required node-20 contexts. Evidence:
|
Summary
BodyReadable.dump()so Bun-compatible response bodies can be discarded safelyVerification
bun run checkbun test(42 passed)vitest --run(41 passed)webfetch.executeagainst the 1Password CLI docs (HTTP 200, 27,395 markdown bytes)