Fetch API vs Axios: Network Error Handling

When managing HTTP requests in modern web development, understanding how your client library detects and manages failures is critical for building resilient applications. While both the native Fetch API and the third-party library Axios perform asynchronous data fetching using Promises, they handle network errors and bad HTTP response statuses fundamentally differently. The native Fetch API only rejects a promise upon true network disruptions (such as DNS failures or lost connections), treating HTTP error codes like 404 or 500 as successful completions. In contrast, Axios automatically categorizes any HTTP status code outside the 2xx range as an error, providing built-in timeout configurations and structured error objects out of the box.

The Fetch API: Strict Network-Only Rejections

The Fetch API is built natively into modern browsers and Node.js runtimes. Its error handling behavior is defined around the transport layer rather than the application layer.

  • Promise Rejection Criteria: A Fetch promise rejects only when a network error occurs that prevents the request from completing. Examples include being offline, a blocked CORS request, an invalid domain, or a terminated connection.
  • Handling HTTP Errors: If a server responds with an HTTP status code such as 404 Not Found, 401 Unauthorized, or 500 Internal Server Error, Fetch considers the transaction complete. The promise resolves normally, meaning the error will not trigger a .catch() block.
  • Manual Verification: Developers must manually verify the response state by checking the boolean response.ok property (which is true for statuses 200–299) or inspecting response.status.
fetch('https://api.example.com/data')
  .then(response => {
    if (!response.ok) {
      // Must manually throw an error to catch HTTP failures
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    return response.json();
  })
  .then(data => console.log(data))
  .catch(error => {
    // Catches true network failures OR the manually thrown error above
    console.error('Request failed:', error.message);
  });

Axios: Unified and Automatic Error Handling

Axios is a standalone, promise-based HTTP client that standardizes error handling across both browser and Node.js environments.

  • Promise Rejection Criteria: By default, Axios rejects the promise if the request encounters a network failure or if the HTTP response status falls outside the 2xx range.
  • Structured Error Objects: When an error occurs, Axios returns a comprehensive error object that clearly categorizes the failure:
    • error.response: The server responded with a non-2xx status code. Contains status, headers, and response data.
    • error.request: The request was sent, but no response was received (e.g., timeout, network drops).
    • error.message: An issue occurred while setting up the request before it was sent.
  • Custom Status Validation: Axios allows developers to adjust which HTTP status codes throw errors via the validateStatus configuration option.
axios.get('https://api.example.com/data')
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    if (error.response) {
      // Server responded with a status code outside the 2xx range (404, 500, etc.)
      console.error(`HTTP error: ${error.response.status}`);
    } else if (error.request) {
      // Request was made, but no response was received (network failure/offline)
      console.error('Network failure or no response from server');
    } else {
      // Configuration or request setup issue
      console.error('Request setup error:', error.message);
    }
  });

Handling Request Timeouts

Network latency and unresponsive servers require requests to abort after a set period.

  • Fetch API: Fetch does not have a native timeout parameter. To abort a hanging request, developers must instantiate an AbortController, pass its signal into the Fetch configuration, and trigger controller.abort() manually using setTimeout.
  • Axios: Axios includes a dedicated timeout property directly in its configuration (e.g., { timeout: 5000 }). If the request exceeds the threshold, Axios automatically aborts the operation and rejects the promise with an ECONNABORTED error code.

Summary of Differences

  • 4xx and 5xx Statuses: Fetch resolves the promise; Axios rejects the promise automatically.
  • Network Dropouts: Both reject the promise, but Axios categorizes the failure under error.request.
  • Timeout Execution: Fetch requires an AbortController; Axios provides an inline timeout configuration.
  • Error Inspection: Fetch requires manual checks on response.ok or response.status; Axios returns a normalized error schema distinguishing network loss from server-side errors.