Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
FAQs Support
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials

Error Handling in AJAX

Network Errors vs HTTP Errors

There are two distinct categories of errors in AJAX:

  • Network errors — the request never reached the server (no internet, DNS failure, server down, CORS block). With fetch(), the Promise rejects in this case.
  • HTTP errors — the server responded, but with an error status (400, 401, 403, 404, 500). With fetch(), the Promise resolves even for these — you must check response.ok manually.
Handling Both Error Types with Fetch
async function fetchData(url) {
  try {
    const response = await fetch(url);

    // HTTP errors: fetch resolves but response.ok is false
    if (!response.ok) {
      // Try to read error details from the response body
      let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
      try {
        const errorBody = await response.json();
        errorMessage = errorBody.message || errorMessage;
      } catch {
        // response body wasn't JSON — use the status text
      }
      throw new Error(errorMessage);
    }

    return await response.json();

  } catch (error) {
    if (error.name === 'TypeError') {
      // Network error — fetch rejected (no internet, CORS, etc.)
      console.error('Network error:', error.message);
      showUserError('No internet connection. Please try again.');
    } else if (error.name === 'AbortError') {
      console.warn('Request was cancelled');
    } else {
      // HTTP error we threw above
      console.error('Request failed:', error.message);
      showUserError(error.message);
    }
    return null;
  }
}

function showUserError(message) {
  const el = document.getElementById('error-banner');
  el.textContent = message;
  el.style.display = 'block';
}
Timeout Handling with AbortController
// Reusable fetch with timeout
async function fetchWithTimeout(url, options = {}, timeoutMs = 8000) {
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), timeoutMs);

  try {
    const response = await fetch(url, { ...options, signal: controller.signal });
    clearTimeout(timeoutId);

    if (!response.ok) throw new Error(`HTTP ${response.status}`);
    return await response.json();

  } catch (error) {
    clearTimeout(timeoutId);
    if (error.name === 'AbortError') {
      throw new Error(`Request timed out after ${timeoutMs}ms`);
    }
    throw error;
  }
}

// Usage
fetchWithTimeout('/api/data', {}, 5000)
  .then(data => console.log(data))
  .catch(err => console.error(err.message));
Retry Logic with Exponential Backoff
// Retry a fetch up to maxRetries times with exponential backoff
async function fetchWithRetry(url, options = {}, maxRetries = 3) {
  let lastError;

  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await fetch(url, options);

      // Don't retry client errors (4xx) — only server errors (5xx) or network issues
      if (response.status >= 400 && response.status < 500) {
        throw new Error(`Client error: ${response.status}`);
      }
      if (!response.ok) throw new Error(`Server error: ${response.status}`);

      return await response.json();

    } catch (error) {
      lastError = error;

      // Don't retry client errors
      if (error.message.startsWith('Client error')) throw error;

      if (attempt < maxRetries) {
        const delay = Math.pow(2, attempt) * 500; // 1s, 2s, 4s
        console.warn(`Attempt ${attempt} failed. Retrying in ${delay}ms...`);
        await new Promise(resolve => setTimeout(resolve, delay));
      }
    }
  }

  throw new Error(`All ${maxRetries} attempts failed: ${lastError.message}`);
}

// Usage
fetchWithRetry('/api/unstable-endpoint')
  .then(data => console.log('Success:', data))
  .catch(err => console.error('Gave up:', err.message));

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.