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.6.0

error-handling.md docs/

1
# Error Handling
2
3
Comprehensive error handling system with detailed error information, type-safe error checking, and specific error codes for different failure scenarios.
4
5
## Capabilities
6
7
### AxiosError Class
8
9
Main error class for axios-specific errors with detailed diagnostic information.
10
11
```typescript { .api }
12
class AxiosError<T = unknown, D = any> extends Error {
13
/**
14
* Creates new AxiosError
15
* @param message - Error message
16
* @param code - Error code
17
* @param config - Request configuration
18
* @param request - Request object
19
* @param response - Response object (if received)
20
*/
21
constructor(
22
message?: string,
23
code?: string,
24
config?: InternalAxiosRequestConfig<D>,
25
request?: any,
26
response?: AxiosResponse<T, D>
27
);
28
29
/** Request configuration that caused the error */
30
config?: InternalAxiosRequestConfig<D>;
31
32
/** Error code identifying the error type */
33
code?: string;
34
35
/** Request object (platform-specific) */
36
request?: any;
37
38
/** Response object (if server responded) */
39
response?: AxiosResponse<T, D>;
40
41
/** Always true for AxiosError instances */
42
isAxiosError: boolean;
43
44
/** HTTP status code from response */
45
status?: number;
46
47
/** Original error that caused this error */
48
cause?: Error;
49
50
/** Convert error to JSON object */
51
toJSON(): object;
52
53
/**
54
* Create AxiosError from existing error
55
* @param error - Original error
56
* @param code - Error code
57
* @param config - Request configuration
58
* @param request - Request object
59
* @param response - Response object
60
* @param customProps - Additional properties
61
* @returns New AxiosError instance
62
*/
63
static from<T = unknown, D = any>(
64
error: Error | unknown,
65
code?: string,
66
config?: InternalAxiosRequestConfig<D>,
67
request?: any,
68
response?: AxiosResponse<T, D>,
69
customProps?: object
70
): AxiosError<T, D>;
71
}
72
```
73
74
**Usage Examples:**
75
76
```typescript
77
import axios, { AxiosError } from "axios";
78
79
try {
80
const response = await axios.get("https://api.example.com/users/999");
81
} catch (error) {
82
if (error instanceof AxiosError) {
83
console.log("Error message:", error.message);
84
console.log("Error code:", error.code);
85
console.log("Status code:", error.status);
86
87
if (error.response) {
88
// Server responded with error status
89
console.log("Response data:", error.response.data);
90
console.log("Status:", error.response.status);
91
console.log("Headers:", error.response.headers);
92
} else if (error.request) {
93
// Request was made but no response received
94
console.log("No response received:", error.request);
95
} else {
96
// Something else happened
97
console.log("Request setup error:", error.message);
98
}
99
100
// Access request config
101
console.log("Request URL:", error.config?.url);
102
console.log("Request method:", error.config?.method);
103
}
104
}
105
```
106
107
### Error Type Checking
108
109
Type-safe functions to identify axios errors and cancellations.
110
111
```typescript { .api }
112
/**
113
* Check if error is an axios error
114
* @param payload - Value to check
115
* @returns Type predicate indicating if value is AxiosError
116
*/
117
function isAxiosError<T = any, D = any>(payload: any): payload is AxiosError<T, D>;
118
119
/**
120
* Check if error is a cancellation
121
* @param value - Value to check
122
* @returns Type predicate indicating if value is Cancel
123
*/
124
function isCancel(value: any): value is Cancel;
125
```
126
127
**Usage Examples:**
128
129
```typescript
130
import axios, { isAxiosError, isCancel } from "axios";
131
132
try {
133
const response = await axios.get("https://api.example.com/data");
134
} catch (error) {
135
if (isAxiosError(error)) {
136
// TypeScript knows this is an AxiosError
137
console.log("Axios error occurred:", error.message);
138
139
if (error.response?.status === 404) {
140
console.log("Resource not found");
141
} else if (error.response?.status === 401) {
142
console.log("Unauthorized - redirecting to login");
143
redirectToLogin();
144
} else if (error.code === "ECONNABORTED") {
145
console.log("Request timeout");
146
}
147
} else if (isCancel(error)) {
148
console.log("Request was cancelled:", error.message);
149
} else {
150
// Regular Error or other type
151
console.log("Non-axios error:", error);
152
}
153
}
154
```
155
156
### Error Codes
157
158
Standard error codes provided by AxiosError for different failure scenarios.
159
160
```typescript { .api }
161
// Network and connection errors
162
static readonly ERR_NETWORK = "ERR_NETWORK";
163
static readonly ECONNABORTED = "ECONNABORTED";
164
static readonly ETIMEDOUT = "ETIMEDOUT";
165
166
// Request configuration errors
167
static readonly ERR_BAD_OPTION_VALUE = "ERR_BAD_OPTION_VALUE";
168
static readonly ERR_BAD_OPTION = "ERR_BAD_OPTION";
169
static readonly ERR_INVALID_URL = "ERR_INVALID_URL";
170
171
// Response errors
172
static readonly ERR_BAD_RESPONSE = "ERR_BAD_RESPONSE";
173
static readonly ERR_BAD_REQUEST = "ERR_BAD_REQUEST";
174
175
// Redirect errors
176
static readonly ERR_FR_TOO_MANY_REDIRECTS = "ERR_FR_TOO_MANY_REDIRECTS";
177
178
// Feature support errors
179
static readonly ERR_NOT_SUPPORT = "ERR_NOT_SUPPORT";
180
static readonly ERR_DEPRECATED = "ERR_DEPRECATED";
181
182
// Cancellation errors
183
static readonly ERR_CANCELED = "ERR_CANCELED";
184
```
185
186
**Usage Examples:**
187
188
```typescript
189
import axios, { AxiosError } from "axios";
190
191
try {
192
const response = await axios.get("https://api.example.com/data", {
193
timeout: 5000
194
});
195
} catch (error) {
196
if (error instanceof AxiosError) {
197
switch (error.code) {
198
case AxiosError.ETIMEDOUT:
199
case AxiosError.ECONNABORTED:
200
console.log("Request timed out - retrying...");
201
// Implement retry logic
202
break;
203
204
case AxiosError.ERR_NETWORK:
205
console.log("Network error - check connection");
206
showNetworkErrorMessage();
207
break;
208
209
case AxiosError.ERR_BAD_REQUEST:
210
console.log("Bad request - check request parameters");
211
break;
212
213
case AxiosError.ERR_FR_TOO_MANY_REDIRECTS:
214
console.log("Too many redirects");
215
break;
216
217
case AxiosError.ERR_CANCELED:
218
console.log("Request was cancelled");
219
break;
220
221
default:
222
console.log("Unknown error:", error.code);
223
}
224
}
225
}
226
```
227
228
### CanceledError Class
229
230
Specific error class for cancelled requests.
231
232
```typescript { .api }
233
class CanceledError<T> extends AxiosError<T> {
234
// Inherits all properties and methods from AxiosError
235
}
236
```
237
238
**Usage Examples:**
239
240
```typescript
241
import axios, { CanceledError } from "axios";
242
243
const controller = new AbortController();
244
245
try {
246
const response = await axios.get("https://api.example.com/data", {
247
signal: controller.signal
248
});
249
} catch (error) {
250
if (error instanceof CanceledError) {
251
console.log("Request was cancelled specifically");
252
} else {
253
console.log("Other error occurred");
254
}
255
}
256
257
// Cancel the request
258
controller.abort();
259
```
260
261
### Error Response Handling
262
263
Handle different types of error responses from servers.
264
265
**Usage Examples:**
266
267
```typescript
268
import axios, { AxiosError } from "axios";
269
270
async function handleApiCall() {
271
try {
272
const response = await axios.post("https://api.example.com/users", {
273
name: "John",
274
email: "invalid-email" // Invalid data
275
});
276
return response.data;
277
} catch (error) {
278
if (error instanceof AxiosError && error.response) {
279
const { status, data } = error.response;
280
281
switch (status) {
282
case 400:
283
// Bad Request - validation errors
284
console.log("Validation errors:", data.errors);
285
displayValidationErrors(data.errors);
286
break;
287
288
case 401:
289
// Unauthorized
290
console.log("Authentication required");
291
redirectToLogin();
292
break;
293
294
case 403:
295
// Forbidden
296
console.log("Access denied");
297
showAccessDeniedMessage();
298
break;
299
300
case 404:
301
// Not Found
302
console.log("Resource not found");
303
showNotFoundMessage();
304
break;
305
306
case 409:
307
// Conflict
308
console.log("Resource conflict:", data.message);
309
handleConflict(data);
310
break;
311
312
case 422:
313
// Unprocessable Entity
314
console.log("Data validation failed:", data.errors);
315
displayFormErrors(data.errors);
316
break;
317
318
case 429:
319
// Too Many Requests
320
console.log("Rate limited. Retry after:", error.response.headers["retry-after"]);
321
scheduleRetry(error.response.headers["retry-after"]);
322
break;
323
324
case 500:
325
// Internal Server Error
326
console.log("Server error occurred");
327
showServerErrorMessage();
328
break;
329
330
case 503:
331
// Service Unavailable
332
console.log("Service temporarily unavailable");
333
showMaintenanceMessage();
334
break;
335
336
default:
337
console.log(`Unexpected error: ${status}`);
338
showGenericErrorMessage();
339
}
340
} else if (error instanceof AxiosError && error.request) {
341
// Network error - no response received
342
console.log("Network error - no response received");
343
showNetworkErrorMessage();
344
} else {
345
// Other error
346
console.log("Unexpected error:", error);
347
showGenericErrorMessage();
348
}
349
350
throw error; // Re-throw if needed
351
}
352
}
353
```
354
355
### Custom Error Handling
356
357
Create custom error handling patterns and error recovery mechanisms.
358
359
**Usage Examples:**
360
361
```typescript
362
import axios, { AxiosError, AxiosResponse } from "axios";
363
364
// Retry function with exponential backoff
365
async function retryRequest<T>(
366
requestFn: () => Promise<AxiosResponse<T>>,
367
maxRetries: number = 3,
368
baseDelay: number = 1000
369
): Promise<AxiosResponse<T>> {
370
let lastError: AxiosError;
371
372
for (let attempt = 0; attempt <= maxRetries; attempt++) {
373
try {
374
return await requestFn();
375
} catch (error) {
376
lastError = error as AxiosError;
377
378
// Don't retry client errors (4xx) except 429
379
if (lastError.response?.status && lastError.response.status >= 400 && lastError.response.status < 500 && lastError.response.status !== 429) {
380
throw lastError;
381
}
382
383
// Don't retry if no more attempts
384
if (attempt === maxRetries) {
385
throw lastError;
386
}
387
388
// Wait before retrying (exponential backoff)
389
const delay = baseDelay * Math.pow(2, attempt);
390
await new Promise(resolve => setTimeout(resolve, delay));
391
392
console.log(`Retrying request (attempt ${attempt + 2}/${maxRetries + 1})...`);
393
}
394
}
395
396
throw lastError!;
397
}
398
399
// Usage
400
const response = await retryRequest(
401
() => axios.get("https://api.example.com/unreliable-endpoint"),
402
3, // Max 3 retries
403
1000 // Start with 1 second delay
404
);
405
406
// Error boundary function
407
async function safeApiCall<T>(
408
apiCall: () => Promise<AxiosResponse<T>>,
409
fallbackValue?: T
410
): Promise<{ data: T | undefined; error: AxiosError | null }> {
411
try {
412
const response = await apiCall();
413
return { data: response.data, error: null };
414
} catch (error) {
415
if (error instanceof AxiosError) {
416
console.log("API call failed:", error.message);
417
return { data: fallbackValue, error };
418
}
419
throw error; // Re-throw non-axios errors
420
}
421
}
422
423
// Usage
424
const { data, error } = await safeApiCall(
425
() => axios.get<User[]>("https://api.example.com/users"),
426
[] // Fallback to empty array
427
);
428
429
if (error) {
430
console.log("Using fallback data due to error:", error.message);
431
}
432
console.log("Users:", data);
433
```