Cancel HTTP requests to prevent unnecessary network usage, handle component cleanup, and improve application performance. Axios supports both legacy CancelToken and modern AbortSignal approaches.
Token-based cancellation system for backward compatibility.
/**
* CancelToken constructor
* @param executor - Function that receives cancel function
*/
class CancelToken {
constructor(executor: (cancel: Canceler) => void);
/** Promise that resolves when token is canceled */
promise: Promise<Cancel>;
/** Cancellation reason if canceled */
reason?: Cancel;
/** Throw error if request was canceled */
throwIfRequested(): void;
}
/**
* Create cancel token source
* @returns Object with token and cancel function
*/
CancelToken.source(): CancelTokenSource;
interface CancelTokenSource {
/** Token to use in request config */
token: CancelToken;
/** Function to cancel the request */
cancel: Canceler;
}
interface Canceler {
(message?: string, config?: AxiosRequestConfig, request?: any): void;
}Usage Examples:
import axios from "axios";
// Using CancelToken.source()
const source = axios.CancelToken.source();
axios.get("https://api.example.com/data", {
cancelToken: source.token
}).catch((error) => {
if (axios.isCancel(error)) {
console.log("Request canceled:", error.message);
} else {
console.error("Request failed:", error);
}
});
// Cancel the request
source.cancel("Operation canceled by user");
// Using CancelToken constructor
let cancel;
const cancelToken = new axios.CancelToken((c) => {
cancel = c;
});
axios.post("https://api.example.com/upload", formData, {
cancelToken: cancelToken,
onUploadProgress: (progressEvent) => {
const progress = (progressEvent.loaded / progressEvent.total) * 100;
console.log(`Upload progress: ${progress}%`);
}
});
// Cancel upload
cancel("Upload canceled");Modern browser-standard cancellation using AbortController.
// Uses standard AbortController API
interface AbortController {
/** Signal to pass to axios config */
signal: AbortSignal;
/** Cancel all requests using this signal */
abort(): void;
}
interface AbortSignal {
/** Whether the signal has been aborted */
readonly aborted: boolean;
/** Event handler for abort events */
onabort?: ((this: AbortSignal, ev: Event) => any) | null;
/** Add event listener for abort */
addEventListener(type: "abort", listener: (ev: Event) => void): void;
/** Remove event listener for abort */
removeEventListener(type: "abort", listener: (ev: Event) => void): void;
}Usage Examples:
// Basic AbortController usage
const controller = new AbortController();
axios.get("https://api.example.com/users", {
signal: controller.signal
}).catch((error) => {
if (error.name === "AbortError" || axios.isCancel(error)) {
console.log("Request aborted");
} else {
console.error("Request failed:", error);
}
});
// Abort the request
controller.abort();
// Timeout with AbortController
function fetchWithTimeout(url, timeout = 5000) {
const controller = new AbortController();
const timeoutId = setTimeout(() => {
controller.abort();
}, timeout);
return axios.get(url, { signal: controller.signal })
.finally(() => clearTimeout(timeoutId));
}
// Usage
fetchWithTimeout("https://api.example.com/slow-endpoint", 3000)
.then(response => console.log(response.data))
.catch(error => {
if (error.name === "AbortError") {
console.log("Request timed out");
}
});Check if an error was caused by request cancellation.
/**
* Check if error is due to request cancellation
* @param value - Error or any value to check
* @returns True if value is a cancellation error
*/
axios.isCancel(value: any): boolean;
/**
* Check if error is an AxiosError (includes cancellation errors)
* @param payload - Error or any value to check
* @returns True if payload is an AxiosError
*/
axios.isAxiosError(payload: any): boolean;Usage Examples:
try {
const response = await axios.get(url, { cancelToken: source.token });
console.log(response.data);
} catch (error) {
if (axios.isCancel(error)) {
console.log("Request was canceled:", error.message);
} else if (axios.isAxiosError(error)) {
console.log("Axios error:", error.message);
console.log("Status:", error.response?.status);
} else {
console.log("Unknown error:", error);
}
}
// With AbortController
try {
const response = await axios.get(url, { signal: controller.signal });
console.log(response.data);
} catch (error) {
if (error.name === "AbortError" || axios.isCancel(error)) {
console.log("Request was aborted");
} else {
console.log("Other error:", error.message);
}
}Objects representing cancellation reasons and errors.
/**
* Cancellation reason object
*/
interface Cancel {
/** Cancellation message */
message: string | undefined;
}
/**
* Error thrown when request is canceled
*/
class CanceledError extends AxiosError {
constructor(message?: string, config?: InternalAxiosRequestConfig, request?: any);
}
// Legacy alias for backward compatibility
const Cancel = CanceledError;Common patterns for canceling requests in React components.
Usage Examples:
import { useEffect, useState } from "react";
import axios from "axios";
// Hook for cancelable requests
function useCancelableRequest() {
useEffect(() => {
const controller = new AbortController();
return () => {
controller.abort(); // Cleanup on unmount
};
}, []);
}
// Component with request cancellation
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(false);
useEffect(() => {
const controller = new AbortController();
async function fetchUser() {
setLoading(true);
try {
const response = await axios.get(`/api/users/${userId}`, {
signal: controller.signal
});
setUser(response.data);
} catch (error) {
if (!axios.isCancel(error)) {
console.error("Failed to fetch user:", error);
}
} finally {
setLoading(false);
}
}
fetchUser();
return () => {
controller.abort(); // Cancel on cleanup
};
}, [userId]);
return loading ? <div>Loading...</div> : <div>{user?.name}</div>;
}
// Custom hook for API calls
function useAPI(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
const controller = new AbortController();
async function fetchData() {
setLoading(true);
setError(null);
try {
const response = await axios.get(url, {
signal: controller.signal
});
setData(response.data);
} catch (err) {
if (!axios.isCancel(err)) {
setError(err);
}
} finally {
setLoading(false);
}
}
if (url) {
fetchData();
}
return () => {
controller.abort();
};
}, [url]);
return { data, loading, error };
}Cancel multiple requests with a single signal or token.
Usage Examples:
// Cancel multiple requests with one controller
const controller = new AbortController();
const requests = [
axios.get("/api/users", { signal: controller.signal }),
axios.get("/api/posts", { signal: controller.signal }),
axios.get("/api/comments", { signal: controller.signal })
];
Promise.allSettled(requests)
.then(results => {
results.forEach((result, index) => {
if (result.status === "fulfilled") {
console.log(`Request ${index} succeeded:`, result.value.data);
} else if (!axios.isCancel(result.reason)) {
console.log(`Request ${index} failed:`, result.reason.message);
}
});
});
// Cancel all requests
controller.abort();
// With CancelToken
const source = axios.CancelToken.source();
const cancelableRequests = [
axios.get("/api/data1", { cancelToken: source.token }),
axios.get("/api/data2", { cancelToken: source.token }),
axios.get("/api/data3", { cancelToken: source.token })
];
// Cancel all
source.cancel("Batch operation canceled");Distinguish between timeouts and manual cancellation.
Usage Examples:
// Combine timeout with manual cancellation
function fetchWithTimeoutAndCancel(url, timeout = 5000) {
const controller = new AbortController();
let timeoutId;
const request = axios.get(url, {
signal: controller.signal,
timeout: timeout // Axios timeout
});
// Manual timeout using AbortController
const timeoutPromise = new Promise((_, reject) => {
timeoutId = setTimeout(() => {
controller.abort();
reject(new Error("Request timed out"));
}, timeout);
});
return Promise.race([request, timeoutPromise])
.finally(() => clearTimeout(timeoutId));
}
// Error handling for different cancellation types
try {
const response = await axios.get(url, {
signal: controller.signal,
timeout: 5000
});
} catch (error) {
if (axios.isCancel(error)) {
console.log("Request was manually canceled");
} else if (error.code === "ECONNABORTED") {
console.log("Request timed out");
} else {
console.log("Other error:", error.message);
}
}