Skip to content

fix(fetch): preserve abort reasons in fetch adapter#10806

Merged
jasonsaayman merged 2 commits intoaxios:v1.xfrom
zozo123:codex/fetch-timeout-safari
Apr 27, 2026
Merged

fix(fetch): preserve abort reasons in fetch adapter#10806
jasonsaayman merged 2 commits intoaxios:v1.xfrom
zozo123:codex/fetch-timeout-safari

Conversation

@zozo123
Copy link
Copy Markdown
Contributor

@zozo123 zozo123 commented Apr 27, 2026

Summary

Fixes #7190.

This is a fallback PR based on the existing work in #7191, because pushing a follow-up commit to Mostafa-Khairy0:fix-fetch-timeout-safari was denied by GitHub. Credit goes to @Mostafa-Khairy0 for the original PR and to @jasonsaayman for narrowing the fix to axios' composed abort reason.

What changed

  • Normalize fetch abort failures through composedSignal.reason before reading the caught error. This avoids Safari DOMException-like getter failures.
  • Preserve timeout semantics as AxiosError with ETIMEDOUT.
  • Preserve user cancellation as CanceledError / ERR_CANCELED instead of reclassifying it as timeout.
  • Update the Bun fetch timeout smoke expectation to ETIMEDOUT, matching the fetch adapter timeout path.

Tests

  • npm run test:vitest:unit -- tests/unit/adapters/fetch.test.js
  • npm run test:vitest:unit -- tests/unit/composeSignals.test.js
  • npm run build

npm run test:smoke:bun was not run locally because Bun is not installed in this environment.


Summary by cubic

Fixes Safari abort handling in the fetch adapter by preserving the composed abort reason and correctly distinguishing timeouts (ETIMEDOUT) from user cancels (ERR_CANCELED). This prevents DOMException getter crashes and makes error behavior consistent across runtimes.

Description

  • Summary of changes

    • Read abort reason from composedSignal.reason before inspecting the thrown error.
    • Timeouts now throw AxiosError with code ETIMEDOUT; user cancels throw CanceledError with ERR_CANCELED.
    • Attach the original thrown error as cause when propagating the composed abort reason, and keep config/request on the error.
    • Updated Bun smoke test to expect ETIMEDOUT for fetch adapter timeouts.
  • Reasoning

    • Safari can reject with DOMException-like objects whose getters throw; touching name/message can crash.
    • Using the composed signal preserves timeout vs cancel semantics safely.
  • Additional context

    • Aligns the fetch adapter’s timeout path with existing timeout semantics in axios.

Docs

  • Update /docs/ to clarify:
    • fetch adapter timeout errors use ETIMEDOUT.
    • Cancellation errors use ERR_CANCELED and are detectable via axios.isCancel(err) or CanceledError.
    • Note Safari’s DOMException behavior and the adapter’s normalization.

Testing

  • Added unit tests in tests/unit/adapters/fetch.test.js:
    • Timeout returns AxiosError with ETIMEDOUT.
    • User-initiated abort returns CanceledError (ERR_CANCELED) even with Safari-like broken DOMException.
    • Broken DOMException on abort during timeout surfaces as ETIMEDOUT.
  • Hardened unit tests by using ephemeral ports to reduce flakiness.
  • Updated smoke test in tests/smoke/bun/tests/timeout.smoke.test.ts to expect ETIMEDOUT.
  • No further tests needed.

Semantic version impact

  • Patch: bug fix in fetch adapter error normalization.
  • Note: timeout code for the fetch adapter is now ETIMEDOUT (was ECONNABORTED in some cases). Consumers checking for timeout by code should handle ETIMEDOUT.

Written for commit 3ff04a2. Summary will update on new commits. Review in cubic

Based on the work in axios#7191.

Co-authored-by: Mostafa-Khairy0 <mostafakhairy0305@gmail.com>
Co-authored-by: Jason Saayman <jasonsaayman@gmail.com>
@zozo123 zozo123 force-pushed the codex/fetch-timeout-safari branch from 8495afd to 9e4cbce Compare April 27, 2026 13:51
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 3 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

@jasonsaayman
Copy link
Copy Markdown
Member

Note for the final release notes when they land:
fetch adapter timeouts now consistently produce AxiosError with code ETIMEDOUT (some runtimes previously produced ECONNABORTED). User-initiated aborts now consistently produce CanceledError. If you were branching on err.code === 'ECONNABORTED' for fetch-adapter timeouts, switch to ETIMEDOUT (or check both during the transition).

@jasonsaayman jasonsaayman reopened this Apr 27, 2026
@jasonsaayman jasonsaayman merged commit 2344aab into axios:v1.x Apr 27, 2026
32 of 49 checks passed
@zozo123 zozo123 deleted the codex/fetch-timeout-safari branch April 27, 2026 15:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Axios fetch adapter throws TypeError on timeout in Safari

2 participants