fix: make discardBody safe when response body lacks dump

Closed
IN
1mo ago
+81-7

Problem

Running the extension inside a host whose module resolution maps undici to a build where request() bodies lack dump() crashed the entire host process with:

TypeError: body.dump is not a function. (In 'body.dump({ limit: 1024 })', 'body.dump' is undefined)
      at discardBody (src/webfetch/fetcher.ts:213:14)

Two defects combined here:

  1. discardBody assumed body.dump() always exists. In some runtimes (bundled loaders, alternate undici resolutions) the response body is a plain stream without it, so discarding a redirect or oversized body throws.
  2. The existing fallback called body.destroy(error), re-emitting the caught error on a stream that has no error listener. An unhandled stream error event escapes as an uncaught exception and kills the host agent process instead of failing a single tool call.

Fix

  • Make dump optional on ResponseBodyStream and feature-check before calling it.
  • When dump is unavailable, drain the body via async iteration bounded by MAX_RESPONSE_SIZE_BYTES.
  • Swallow discard failures (best-effort by definition) and destroy the stream quietly: attach a no-op error listener before destroy() so nothing can escape as unhandled.

Testing

  • New test/discard-body.test.ts: body without dump drains and resolves; mid-stream failure resolves without surfacing; dump-capable body still uses dump.
  • npm run check and full npm test pass (43 tests).

Summary by cubic

Prevents host crashes by making discardBody safe when response bodies lack dump in environments resolving undici to builds without it. Previously it called dump() and then destroy(error), causing a TypeError or an unhandled stream error; now it feature-checks dump, drains with a size cap, and destroys quietly.

  • Uses body.dump({ limit: 1024 }) when available; otherwise drains via async iteration bounded by MAX_RESPONSE_SIZE_BYTES.
  • Swallows discard errors; attaches a no-op error listener before destroy() to avoid uncaught exceptions.
  • No behavior change when dump exists; only failure handling differs.
  • Adds tests for bodies without dump, mid-stream failures, and dump-capable bodies.