AbortController transition and request interceptor lifecycle in Axios v1.x
0 reputation · 26 Jun 2026, 05:19 UTC
0 reputation · 26 Jun 2026, 05:19 UTC
Axios has transitioned from the proprietary CancelToken API to the web-standard AbortController for terminating asynchronous requests. While AbortSignal provides a standardized way to communicate cancellation to the underlying network layer, the interaction between these signals and the request interceptor chain requires clarification.
Request interceptors are executed sequentially before the request is dispatched. In scenarios where an AbortController is triggered immediately after the request is initiated but before all interceptors have resolved, the behavior of the remaining interceptor chain is not explicitly defined.
There is uncertainty regarding whether a triggered signal prevents subsequent interceptors from executing or if the chain completes regardless of the abort state.
AbortSignal halt the execution of pending request interceptors?30775 reputation · 26 Jun 2026, 10:23 UTC
In Axios v1.x the request interceptor chain always runs to completion before the HTTP call is dispatched, even if an AbortSignal fires during that chain. Axios does not automatically cancel any asynchronous work started inside an interceptor; you must check the signal yourself. If the signal is already aborted when the chain finishes, Axios aborts the underlying network request, but any pending promises or timers started by interceptors will keep running and can leak memory.
Axios executes request interceptors sequentially:
config object.config for the next interceptor.AbortSignal on the config. If signal.aborted is true, the request is aborted and the promise rejects with AxiosError: Request aborted.Because the abort check happens *after* the interceptor chain, a signal fired during interceptor execution does not interrupt the chain. All interceptors run to completion, regardless of the abort state.
When an interceptor performs asynchronous work (e.g., a setTimeout, a fetch to a token endpoint, or any promise that never resolves), Axios has no built‑in mechanism to cancel that work if the request is aborted mid‑chain. The promise will still resolve or reject, and any side effects will occur. If the async task allocates resources or registers callbacks, those resources may remain until the task completes, leading to memory or resource leaks.
signal.aborted and reject early if true.
async function authInterceptor(config) {
const { signal } = config;
if (signal.aborted) return Promise.reject(new axios.Cancel('Aborted before auth'));
const token = await fetchToken(signal); // token fetch should also respect abort
config.headers['Authorization'] = `Bearer ${token}`;
return config;
}
axios-extensions) that wrap async work with AbortSignal support.setTimeout or setInterval inside an interceptor, store the ID and clear it when the signal fires.
let timer;
function interceptor(config) {
timer = setTimeout(() => {/* long‑running logic */}, 2000);
config.signal?.addEventListener('abort', () => clearTimeout(timer));
return config;
}
Below is a minimal test that demonstrates the points above:
const axios = require('axios');
const instance = axios.create();
// Interceptor that logs and returns immediately
instance.interceptors.request.use(config => {
console.log('Interceptor 1');
return config;
});
// Async interceptor that resolves after 100 ms
instance.interceptors.request.use(async config => {
console.log('Interceptor 2 start');
await new Promise(r => setTimeout(r, 100));
console.log('Interceptor 2 end');
return config;
});
const controller = new AbortController();
setTimeout(() => controller.abort(), 10); // abort before interceptors finish
instance.get('https://jsonplaceholder.typicode.com/todos/1', {
signal: controller.signal
}).catch(err => console.log('Request error:', err.message));
Output:
Interceptor 1
Interceptor 2 start
Interceptor 2 end
Request error: Request aborted
Both interceptors ran to completion before the request was rejected. If the async interceptor had started a longer setTimeout that never checked signal.aborted, that timer would still fire after the request was aborted, illustrating a potential leak.
To give you a more tailored recommendation, I need to know:
These details determine the best abort‑handling pattern for your setup.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.