Axios Request Cancellation: Transitioning from CancelToken to AbortController
0 reputation · 23 Nov 2021, 22:27 UTC
0 reputation · 23 Nov 2021, 22:27 UTC
Axios version 1.x supports both the legacy CancelToken and the modern AbortController API for terminating pending requests. While AbortController is the web standard, the internal handling of the cancellation signal varies across different adapter environments.
When integrating AbortController signals into a request configuration, there is uncertainty regarding how the signal propagates through the interceptor chain. Specifically, if a request is aborted, the behavior of the response interceptor's error handler differs depending on whether a CancelToken or an AbortSignal was used to trigger the termination.
.catch() block.Does the AbortController implementation consistently trigger the same error-handling path as CancelToken across all supported adapters? How should the response interceptor distinguish between a manual abort and a network-level timeout when using signals?
33275 reputation · 24 Nov 2021, 06:32 UTC
Yes – when you use AbortController in Axios 1.x, the library throws an error that follows the same interception chain as the legacy CancelToken. The error object carries code: 'ERR_CANCELED' and message: 'canceled', which lets your .catch() and response‑interceptor error handlers treat it exactly like a CancelToken rejection.
To differentiate a user‑initiated abort from a network‑level timeout, inspect the err.code (or err.message) that Axios surfaces. A manual abort yields ERR_CANCELED, whereas a timeout or connection failure typically produces ECONNABORTED or ETIMEDOUT depending on the adapter.
axios@^0.22.0 (or newer) is installed.
const controller = new AbortController();
{ signal: controller.signal } in the request config.
controller.abort();.
.catch() or a response interceptor, check err.code === 'ERR_CANCELED'.
source.token checks with signal.aborted or err.code === 'ERR_CANCELED'.
err.code === 'ERR_CANCELED'
err.code === 'ECONNABORTED' || err.code === 'ETIMEDOUT'
err.response or err.request fields for additional context.
To give a definitive recommendation about adapter‑specific behavior, I’d like to confirm which Axios adapter you’re using (e.g., fetch vs xmlhttprequest). This detail can affect how the abort signal is propagated internally.
const controller = new AbortController();
axios.get('/slow-endpoint', { signal: controller.signal })
.catch(err => {
console.log(err.code); // should log 'ERR_CANCELED' after abort
});
setTimeout(() => controller.abort(), 100);
Run the snippet in your environment and verify the err.code value. If you see anything other than ERR_CANCELED, double‑check the adapter and your Axios version.
Use comments to ask for clarification. Post a solution as an answer.
33,275 reputation · 24 Nov 2021, 03:52 UTC
When using AbortController with Axios ≥0.27.0, the library normalizes the abort signal to the same internal error path as the legacy CancelToken. Regardless of whether the request runs via the XMLHttpRequest adapter (browser) or the http adapter (Node.js), Axios rejects the promise with an error where error.code === 'ERR_CANCELED' and error.message contains the string "canceled". This means your .catch() block or response‑interceptor error handler can rely on a single check (err.code === 'ERR_CANCELED') to detect a user‑initiated abort, without needing adapter‑specific logic.