How to Catch and Inspect Axios Error Status Codes for Precise HTTP Handling
Wrap Axios requests in try/catch blocks, verify that error.response exists to confirm the server returned a response, then read the numeric error.response.status property to branch logic for specific HTTP codes like 401, 404, or 429.
When working with the Axios HTTP client, robust error handling requires inspecting the exact status code returned by the server. While this guide focuses on JavaScript patterns, the architectural approach mirrors the Python Requests library (psf/requests), specifically the error handling logic found in src/requests/exceptions.py and response modeling in src/requests/models.py.
Understanding the Axios Error Object Structure
Axios wraps HTTP failures in a specialized Error object that extends the native JavaScript Error class. When a request fails with a status outside the 2xx range, or when a network error occurs, Axios populates specific fields that allow you to diagnose the failure.
The complete object shape is:
{
// Standard error fields
message: string,
name: 'AxiosError',
// Axios-specific fields
config: Object, // request configuration
code: string|null, // e.g., 'ECONNABORTED'
request: XMLHttpRequest|http.ClientRequest,
response: {
data: any,
status: number, // <-- the HTTP status you need
statusText: string,
headers: Object,
config: Object,
request: Object
},
isAxiosError: true
}
Key insight: The response property is only present when the server returns a complete HTTP response. If the request fails at the network level (DNS failure, timeout, CORS issue), response will be undefined and code will contain a string like ECONNABORTED.
Step-by-Step: Catch and Inspect Status Codes
Wrap Requests in try/catch Blocks
Always wrap Axios calls in try/catch when using async/await, or attach a .catch() handler for promise chains. This guarantees you intercept any network or server error before it crashes your application.
try {
const response = await axios.get('https://api.example.com/data');
return response.data;
} catch (error) {
// Error handling logic goes here
}
Verify error.response Exists
Before inspecting the status code, confirm that error.response is truthy. This check distinguishes between HTTP errors (server responded with 4xx/5xx) and network errors (no response received).
if (axios.isAxiosError(error) && error.response) {
// Server returned a response with a status code
console.log('HTTP Status:', error.response.status);
} else {
// Network error, timeout, or request was not sent
console.log('Network Error:', error.code);
}
Inspect error.response.status
Once you confirm error.response exists, read the status property to obtain the numeric HTTP code. Use this value in conditional logic to handle specific scenarios like authentication failures or rate limiting.
const { status, data } = error.response;
switch (status) {
case 401:
// Handle unauthorized access
break;
case 429:
// Handle rate limiting
break;
default:
console.error(`Unexpected HTTP ${status}:`, data);
}
Practical Implementation Patterns
The following pattern demonstrates robust error handling for a user-fetching function, including specific handling for 401, 404, and 429 status codes:
import axios from 'axios';
async function fetchUser(id) {
try {
const resp = await axios.get(`https://api.example.com/users/${id}`);
return resp.data; // 2xx – success
} catch (err) {
if (axios.isAxiosError(err) && err.response) {
// Server responded with a status outside 2xx
const { status, data } = err.response;
switch (status) {
case 401:
// Unauthorized – maybe refresh token
handleAuthFailure();
break;
case 404:
// Not found – inform caller
throw new Error('User not found');
case 429:
// Too many requests – back‑off
await waitBeforeRetry();
return fetchUser(id); // retry
default:
// Other errors – generic handling
console.error(`HTTP ${status}:`, data);
throw err;
}
} else {
// No response – network or config error
console.error('Network error', err);
throw err;
}
}
}
Centralized Error Handling with Interceptors
For applications requiring consistent status-code handling across many API calls, register a response interceptor once on the Axios instance. This avoids repeating error-handling logic in every function.
axios.interceptors.response.use(
res => res, // pass through 2xx responses
err => {
if (err.response) {
// Centralized status handling
const { status } = err.response;
if (status === 401) {
redirectToLogin();
} else if (status === 503) {
showMaintenanceModal();
}
}
return Promise.reject(err); // keep error propagation
}
);
Comparison with Python Requests
The error-handling philosophy in Axios closely mirrors the Python Requests library (psf/requests). Understanding both implementations helps maintain consistent patterns across JavaScript and Python codebases.
In Requests, HTTP errors are represented by requests.exceptions.HTTPError, defined in src/requests/exceptions.py. Unlike Axios, which rejects the promise automatically for non-2xx status codes, Requests requires you to explicitly call Response.raise_for_status() to trigger an exception. Once raised, the exception carries the original Response object, allowing you to inspect exc.response.status_code just as you would access err.response.status in Axios.
The Response class, implemented in src/requests/models.py, stores the status_code as an integer and provides the raise_for_status() method that determines whether to throw based on the status code range.
| Scenario | Axios (JavaScript) | Requests (Python) |
|---|---|---|
| Successful request | await axios.get(url) returns response with status === 200 |
requests.get(url).status_code == 200 |
| 4xx/5xx response | Caught in catch block; err.response.status holds the code |
resp.raise_for_status() raises HTTPError; inspect e.response.status_code |
| No server response (timeout) | err.code === 'ECONNABORTED' and !err.response |
requests.exceptions.ConnectTimeout or ReadTimeout is raised |
Summary
- Axios error objects expose HTTP status codes via
error.response.status, but only when the server returns a response. - Always verify
error.responseexists before accessing status to distinguish HTTP errors from network failures. - Use
axios.isAxiosError()to type-check errors and ensure they originate from Axios rather than other application code. - Centralize logic with response interceptors when the same status-code handling applies across multiple endpoints.
- Python Requests follows a similar pattern where
HTTPErrorcarries aresponseobject with astatus_code, as seen insrc/requests/exceptions.pyandsrc/requests/models.py.
Frequently Asked Questions
How do I check if an error is an Axios error?
Use the static method axios.isAxiosError(error) to verify that the caught error originated from Axios. This method returns true only for errors that carry the isAxiosError property, distinguishing them from standard JavaScript errors or exceptions thrown by other libraries.
What is the difference between error.response and error.request?
error.response is present when the server returns a complete HTTP response with a status code outside the 2xx range, allowing you to inspect error.response.status. error.request contains the underlying XMLHttpRequest or Node.js ClientRequest instance and is populated when the request was sent but no response was received, indicating network failures, timeouts, or CORS issues.
How do I handle network errors differently from HTTP errors in Axios?
Check for the absence of error.response. If error.response is undefined and error.code equals ECONNABORTED, ENOTFOUND, or similar, the error is network-related. If error.response exists, the error is an HTTP error and you should branch logic based on error.response.status.
Can I use interceptors to retry failed requests based on status code?
Yes. Register a response interceptor using axios.interceptors.response.use() that inspects error.response.status. For specific codes like 429 (Too Many Requests) or 503 (Service Unavailable), implement a backoff strategy and return a new axios call before rejecting the promise. Ensure you limit retry attempts to avoid infinite loops.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →