# How to Catch and Inspect Axios Error Status Codes for Precise HTTP Handling

> Learn how to catch and inspect Axios error status codes in try/catch blocks. Reliably handle specific HTTP responses like 401 or 404 for precise error management.

- Repository: [Python Software Foundation/requests](https://github.com/psf/requests)
- Tags: how-to-guide
- Published: 2026-02-20

---

**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`](https://github.com/psf/requests/blob/main/src/requests/exceptions.py) and response modeling in [`src/requests/models.py`](https://github.com/psf/requests/blob/main/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:

```javascript
{
  // 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.

```javascript
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).

```javascript
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.

```javascript
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:

```javascript
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.

```javascript
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`](https://github.com/psf/requests/blob/main/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`](https://github.com/psf/requests/blob/main/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.response` exists 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 `HTTPError` carries a `response` object with a `status_code`, as seen in [`src/requests/exceptions.py`](https://github.com/psf/requests/blob/main/src/requests/exceptions.py) and [`src/requests/models.py`](https://github.com/psf/requests/blob/main/src/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.