After 3.3.26 fixed the filecode parsing, the remaining intermittent failure is
a generic "fetch failed" — a transient network error on one of the requests
around the multi-minute upload. Can't tell from one log line whether it's the
server-discovery GET or the post-upload result-submit, so harden both:
- _fetch (the native-fetch chokepoint for discovery, redirects, result-submit):
retry up to 3x with short backoff on a thrown network error, each attempt
bounded by a 20s timeout (Node fetch has none by default). Caller aborts are
not retried. The big file upload (undici) is retried at the upload-manager
level, not here.
- result-submit is now best-effort: if it still fails after retries but we
already hold the filecode from the CDN response, return that instead of
discarding a completed upload.
- label the undici upload-POST error with phase + MB sent + node, preserving the
original message so transient classification still matches.
- eslint: add AbortSignal to globals.
- Tests: _fetch transient-retry path (10 doodstream tests total).
"fetch failed" is already classified transient by upload-manager, so this is
additive resilience; next logs will show if anything still slips through.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>