npm-axios

Description
Promise based HTTP client for the browser and node.js
Author
tessl
Last updated

How to use

npx @tessl/cli registry install tessl/npm-axios@1.11.0

cancellation.md docs/

1
# Request Cancellation
2
3
Cancel HTTP requests to prevent unnecessary network usage, handle component cleanup, and improve application performance. Axios supports both legacy CancelToken and modern AbortSignal approaches.
4
5
## Capabilities
6
7
### CancelToken (Legacy)
8
9
Token-based cancellation system for backward compatibility.
10
11
```javascript { .api }
12
/**
13
* CancelToken constructor
14
* @param executor - Function that receives cancel function
15
*/
16
class CancelToken {
17
constructor(executor: (cancel: Canceler) => void);
18
19
/** Promise that resolves when token is canceled */
20
promise: Promise<Cancel>;
21
/** Cancellation reason if canceled */
22
reason?: Cancel;
23
24
/** Throw error if request was canceled */
25
throwIfRequested(): void;
26
}
27
28
/**
29
* Create cancel token source
30
* @returns Object with token and cancel function
31
*/
32
CancelToken.source(): CancelTokenSource;
33
34
interface CancelTokenSource {
35
/** Token to use in request config */
36
token: CancelToken;
37
/** Function to cancel the request */
38
cancel: Canceler;
39
}
40
41
interface Canceler {
42
(message?: string, config?: AxiosRequestConfig, request?: any): void;
43
}
44
```
45
46
**Usage Examples:**
47
48
```javascript
49
import axios from "axios";
50
51
// Using CancelToken.source()
52
const source = axios.CancelToken.source();
53
54
axios.get("https://api.example.com/data", {
55
cancelToken: source.token
56
}).catch((error) => {
57
if (axios.isCancel(error)) {
58
console.log("Request canceled:", error.message);
59
} else {
60
console.error("Request failed:", error);
61
}
62
});
63
64
// Cancel the request
65
source.cancel("Operation canceled by user");
66
67
// Using CancelToken constructor
68
let cancel;
69
const cancelToken = new axios.CancelToken((c) => {
70
cancel = c;
71
});
72
73
axios.post("https://api.example.com/upload", formData, {
74
cancelToken: cancelToken,
75
onUploadProgress: (progressEvent) => {
76
const progress = (progressEvent.loaded / progressEvent.total) * 100;
77
console.log(`Upload progress: ${progress}%`);
78
}
79
});
80
81
// Cancel upload
82
cancel("Upload canceled");
83
```
84
85
### AbortSignal (Modern)
86
87
Modern browser-standard cancellation using AbortController.
88
89
```javascript { .api }
90
// Uses standard AbortController API
91
interface AbortController {
92
/** Signal to pass to axios config */
93
signal: AbortSignal;
94
/** Cancel all requests using this signal */
95
abort(): void;
96
}
97
98
interface AbortSignal {
99
/** Whether the signal has been aborted */
100
readonly aborted: boolean;
101
/** Event handler for abort events */
102
onabort?: ((this: AbortSignal, ev: Event) => any) | null;
103
/** Add event listener for abort */
104
addEventListener(type: "abort", listener: (ev: Event) => void): void;
105
/** Remove event listener for abort */
106
removeEventListener(type: "abort", listener: (ev: Event) => void): void;
107
}
108
```
109
110
**Usage Examples:**
111
112
```javascript
113
// Basic AbortController usage
114
const controller = new AbortController();
115
116
axios.get("https://api.example.com/users", {
117
signal: controller.signal
118
}).catch((error) => {
119
if (error.name === "AbortError" || axios.isCancel(error)) {
120
console.log("Request aborted");
121
} else {
122
console.error("Request failed:", error);
123
}
124
});
125
126
// Abort the request
127
controller.abort();
128
129
// Timeout with AbortController
130
function fetchWithTimeout(url, timeout = 5000) {
131
const controller = new AbortController();
132
133
const timeoutId = setTimeout(() => {
134
controller.abort();
135
}, timeout);
136
137
return axios.get(url, { signal: controller.signal })
138
.finally(() => clearTimeout(timeoutId));
139
}
140
141
// Usage
142
fetchWithTimeout("https://api.example.com/slow-endpoint", 3000)
143
.then(response => console.log(response.data))
144
.catch(error => {
145
if (error.name === "AbortError") {
146
console.log("Request timed out");
147
}
148
});
149
```
150
151
### Cancellation Detection
152
153
Check if an error was caused by request cancellation.
154
155
```javascript { .api }
156
/**
157
* Check if error is due to request cancellation
158
* @param value - Error or any value to check
159
* @returns True if value is a cancellation error
160
*/
161
axios.isCancel(value: any): boolean;
162
163
/**
164
* Check if error is an AxiosError (includes cancellation errors)
165
* @param payload - Error or any value to check
166
* @returns True if payload is an AxiosError
167
*/
168
axios.isAxiosError(payload: any): boolean;
169
```
170
171
**Usage Examples:**
172
173
```javascript
174
try {
175
const response = await axios.get(url, { cancelToken: source.token });
176
console.log(response.data);
177
} catch (error) {
178
if (axios.isCancel(error)) {
179
console.log("Request was canceled:", error.message);
180
} else if (axios.isAxiosError(error)) {
181
console.log("Axios error:", error.message);
182
console.log("Status:", error.response?.status);
183
} else {
184
console.log("Unknown error:", error);
185
}
186
}
187
188
// With AbortController
189
try {
190
const response = await axios.get(url, { signal: controller.signal });
191
console.log(response.data);
192
} catch (error) {
193
if (error.name === "AbortError" || axios.isCancel(error)) {
194
console.log("Request was aborted");
195
} else {
196
console.log("Other error:", error.message);
197
}
198
}
199
```
200
201
### Cancel and CanceledError
202
203
Objects representing cancellation reasons and errors.
204
205
```javascript { .api }
206
/**
207
* Cancellation reason object
208
*/
209
interface Cancel {
210
/** Cancellation message */
211
message: string | undefined;
212
}
213
214
/**
215
* Error thrown when request is canceled
216
*/
217
class CanceledError extends AxiosError {
218
constructor(message?: string, config?: InternalAxiosRequestConfig, request?: any);
219
}
220
221
// Legacy alias for backward compatibility
222
const Cancel = CanceledError;
223
```
224
225
### React Component Integration
226
227
Common patterns for canceling requests in React components.
228
229
**Usage Examples:**
230
231
```javascript
232
import { useEffect, useState } from "react";
233
import axios from "axios";
234
235
// Hook for cancelable requests
236
function useCancelableRequest() {
237
useEffect(() => {
238
const controller = new AbortController();
239
240
return () => {
241
controller.abort(); // Cleanup on unmount
242
};
243
}, []);
244
}
245
246
// Component with request cancellation
247
function UserProfile({ userId }) {
248
const [user, setUser] = useState(null);
249
const [loading, setLoading] = useState(false);
250
251
useEffect(() => {
252
const controller = new AbortController();
253
254
async function fetchUser() {
255
setLoading(true);
256
try {
257
const response = await axios.get(`/api/users/${userId}`, {
258
signal: controller.signal
259
});
260
setUser(response.data);
261
} catch (error) {
262
if (!axios.isCancel(error)) {
263
console.error("Failed to fetch user:", error);
264
}
265
} finally {
266
setLoading(false);
267
}
268
}
269
270
fetchUser();
271
272
return () => {
273
controller.abort(); // Cancel on cleanup
274
};
275
}, [userId]);
276
277
return loading ? <div>Loading...</div> : <div>{user?.name}</div>;
278
}
279
280
// Custom hook for API calls
281
function useAPI(url) {
282
const [data, setData] = useState(null);
283
const [loading, setLoading] = useState(false);
284
const [error, setError] = useState(null);
285
286
useEffect(() => {
287
const controller = new AbortController();
288
289
async function fetchData() {
290
setLoading(true);
291
setError(null);
292
293
try {
294
const response = await axios.get(url, {
295
signal: controller.signal
296
});
297
setData(response.data);
298
} catch (err) {
299
if (!axios.isCancel(err)) {
300
setError(err);
301
}
302
} finally {
303
setLoading(false);
304
}
305
}
306
307
if (url) {
308
fetchData();
309
}
310
311
return () => {
312
controller.abort();
313
};
314
}, [url]);
315
316
return { data, loading, error };
317
}
318
```
319
320
### Multiple Request Cancellation
321
322
Cancel multiple requests with a single signal or token.
323
324
**Usage Examples:**
325
326
```javascript
327
// Cancel multiple requests with one controller
328
const controller = new AbortController();
329
330
const requests = [
331
axios.get("/api/users", { signal: controller.signal }),
332
axios.get("/api/posts", { signal: controller.signal }),
333
axios.get("/api/comments", { signal: controller.signal })
334
];
335
336
Promise.allSettled(requests)
337
.then(results => {
338
results.forEach((result, index) => {
339
if (result.status === "fulfilled") {
340
console.log(`Request ${index} succeeded:`, result.value.data);
341
} else if (!axios.isCancel(result.reason)) {
342
console.log(`Request ${index} failed:`, result.reason.message);
343
}
344
});
345
});
346
347
// Cancel all requests
348
controller.abort();
349
350
// With CancelToken
351
const source = axios.CancelToken.source();
352
353
const cancelableRequests = [
354
axios.get("/api/data1", { cancelToken: source.token }),
355
axios.get("/api/data2", { cancelToken: source.token }),
356
axios.get("/api/data3", { cancelToken: source.token })
357
];
358
359
// Cancel all
360
source.cancel("Batch operation canceled");
361
```
362
363
### Request Timeout vs Cancellation
364
365
Distinguish between timeouts and manual cancellation.
366
367
**Usage Examples:**
368
369
```javascript
370
// Combine timeout with manual cancellation
371
function fetchWithTimeoutAndCancel(url, timeout = 5000) {
372
const controller = new AbortController();
373
let timeoutId;
374
375
const request = axios.get(url, {
376
signal: controller.signal,
377
timeout: timeout // Axios timeout
378
});
379
380
// Manual timeout using AbortController
381
const timeoutPromise = new Promise((_, reject) => {
382
timeoutId = setTimeout(() => {
383
controller.abort();
384
reject(new Error("Request timed out"));
385
}, timeout);
386
});
387
388
return Promise.race([request, timeoutPromise])
389
.finally(() => clearTimeout(timeoutId));
390
}
391
392
// Error handling for different cancellation types
393
try {
394
const response = await axios.get(url, {
395
signal: controller.signal,
396
timeout: 5000
397
});
398
} catch (error) {
399
if (axios.isCancel(error)) {
400
console.log("Request was manually canceled");
401
} else if (error.code === "ECONNABORTED") {
402
console.log("Request timed out");
403
} else {
404
console.log("Other error:", error.message);
405
}
406
}
407
```