Axios: Detect Manual Abort vs Request Timeout

When working with Axios, handling request termination properly requires distinguishing between a user-triggered cancellation and an automated network timeout. Both scenarios reject the request's promise and trigger the catch block, but Axios assigns distinct error codes and metadata to each event. This article explains how to reliably detect whether an Axios request failed due to a manual abort via AbortController or because it exceeded a configured timeout threshold.

Key Error Properties

Axios assigns specific values to the code property on the generated AxiosError object depending on how the request was terminated:

Implementation Example

The following example demonstrates how to set up an Axios request with both an abort signal and a timeout, and how to inspect the caught error:

import axios from 'axios';

const controller = new AbortController();

async function makeRequest() {
  try {
    const response = await axios.get('https://api.example.com/data', {
      signal: controller.signal, // For manual cancellation
      timeout: 5000              // 5-second timeout limit
    });
    console.log('Data received:', response.data);
  } catch (error) {
    if (axios.isAxiosError(error)) {
      if (axios.isCancel(error) || error.code === 'ERR_CANCELED') {
        console.log('Request was aborted manually by the user or controller.');
      } else if (error.code === 'ECONNABORTED' && error.message.includes('timeout')) {
        console.log('Request failed due to a network timeout.');
      } else {
        console.log('An unexpected HTTP or network error occurred:', error.message);
      }
    } else {
      console.log('Non-Axios error occurred:', error);
    }
  }
}

// To trigger a manual abort:
// controller.abort();

Detection Breakdown

  1. Verify it is an Axios Error: Use axios.isAxiosError(error) to ensure the error object contains Axios-specific metadata.
  2. Check for Manual Aborts: Use axios.isCancel(error) or check error.code === 'ERR_CANCELED'. This condition triggers when controller.abort() is executed.
  3. Check for Timeouts: Evaluate error.code === 'ECONNABORTED'. Combining this with error.message.includes('timeout') provides extra specificity, as ECONNABORTED is the standard POSIX code Axios uses for client-side connection aborts triggered by the timeout timer.