fix(client): retry Node-level transport errors in subscribe/dispatch (#211)
* fix(client): retry Node-level transport errors (ETIMEDOUT, ECONNRESET, ...) `fal.subscribe()` already retries HTTP 429/502/503/504, but transport-layer failures (Node fetch wrapping ETIMEDOUT/ECONNRESET/ENOTFOUND/etc. in a `TypeError: fetch failed`) fell through `isRetryableError` because the function bailed out on any non-`ApiError`. This mirrors the Python client's behavior of retrying `httpx.TransportError` and `httpx.TimeoutException`. Walks the `.cause` chain so it works for both Node's built-in fetch and implementations like `node-fetch` that set `.code` directly. `AbortError` is still skipped, so user-cancelled requests are not retried. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(client): bail on AbortError/TimeoutError anywhere in cause chain Defense-in-depth on top of the previous commit: walk the entire `.cause` chain looking for `name === 'AbortError'` (manual cancellation) or `'TimeoutError'` (signal-driven user timeout, e.g. AbortSignal.timeout) and never retry them. The dispatchRequest layer already short-circuits on `signal.aborted`, but keeping isRetryableNetworkError honest in isolation makes it safe to use directly and future-proofs against unusual wrapping. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(client): bump to 1.10.1 Patch release for the transport-error retry fix. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
R
Ruslan Kuprieiev committed
442a7571dfa5ea5cf9d2a1192113f207f9bd718c
Parent: f12065b
Committed by GitHub <noreply@github.com>
on 5/4/2026, 4:17:59 PM