Chapter 6: Error Handling and Retry Mechanism

Haiyue
6min

Chapter 6: Error Handling and Retry Mechanism

Learning Objectives

  1. Understand Axios error types and structure
  2. Master error handling at different levels
  3. Learn to implement request retry mechanism
  4. Master handling network errors
  5. Implement user-friendly error messages

6.1 Error Type Analysis

Axios Error Structure

// Error object structure
const errorTypes = {
  networkError: {
    description: "Network connection error",
    detection: "!error.response && error.request",
    examples: ["No network connection", "DNS resolution failed", "Server not responding"]
  },

  responseError: {
    description: "Server response error",
    detection: "error.response && error.response.status",
    examples: ["4xx client errors", "5xx server errors"]
  },

  configError: {
    description: "Request configuration error",
    detection: "!error.response && !error.request",
    examples: ["Invalid request configuration", "Interceptor error"]
  }
};

6.2 Unified Error Handling

Error Handler

class ErrorHandler {
  static handle(error) {
    if (error.response) {
      // Server response error
      return this.handleResponseError(error.response);
    } else if (error.request) {
      // Network error
      return this.handleNetworkError(error);
    } else {
      // Configuration error
      return this.handleConfigError(error);
    }
  }

  static handleResponseError(response) {
    const { status, data } = response;

    switch (status) {
      case 400:
        return { message: 'Invalid request parameters', type: 'warning' };
      case 401:
        return { message: 'Unauthorized, please login again', type: 'error' };
      case 403:
        return { message: 'Access forbidden', type: 'error' };
      case 404:
        return { message: 'Requested resource not found', type: 'error' };
      case 500:
        return { message: 'Internal server error', type: 'error' };
      default:
        return { message: data?.message || 'Request failed', type: 'error' };
    }
  }

  static handleNetworkError(error) {
    if (error.code === 'ECONNABORTED') {
      return { message: 'Request timeout, please try again later', type: 'warning' };
    }
    return { message: 'Network connection error, please check your network', type: 'error' };
  }

  static handleConfigError(error) {
    return { message: 'Request configuration error', type: 'error' };
  }
}

6.3 Retry Mechanism

Smart Retry

class RetryHandler {
  constructor(maxRetries = 3, retryDelay = 1000) {
    this.maxRetries = maxRetries;
    this.retryDelay = retryDelay;
  }

  async executeWithRetry(requestFn, config = {}) {
    let lastError;

    for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
      try {
        return await requestFn();
      } catch (error) {
        lastError = error;

        if (attempt === this.maxRetries || !this.shouldRetry(error)) {
          break;
        }

        console.log(`Retry attempt ${attempt}, retrying after ${this.retryDelay * attempt}ms`);
        await this.delay(this.retryDelay * attempt);
      }
    }

    throw lastError;
  }

  shouldRetry(error) {
    // Only retry on network errors and 5xx errors
    return !error.response || error.response.status >= 500;
  }

  delay(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
}

// Using retry mechanism
const retryHandler = new RetryHandler(3, 1000);

async function reliableRequest(url) {
  return retryHandler.executeWithRetry(() => axios.get(url));
}

6.4 Error Boundaries and Recovery

Error Recovery Strategy

class ErrorRecovery {
  static strategies = {
    retry: 'automatic_retry',
    fallback: 'use_cached_data',
    offline: 'queue_for_later',
    degraded: 'reduced_functionality'
  };

  static async handleWithRecovery(requestFn, recoveryOptions = {}) {
    try {
      return await requestFn();
    } catch (error) {
      return this.executeRecovery(error, recoveryOptions);
    }
  }

  static async executeRecovery(error, options) {
    // Choose recovery strategy based on error type
    if (options.fallbackData && this.isNetworkError(error)) {
      console.log('Using cached data');
      return options.fallbackData;
    }

    if (options.retryCount && this.canRetry(error)) {
      console.log('Automatic retry');
      // Execute retry logic
    }

    throw error;
  }

  static isNetworkError(error) {
    return !error.response && error.request;
  }

  static canRetry(error) {
    return !error.response || error.response.status >= 500;
  }
}

Chapter Summary

  • Understand different types of errors and their handling methods
  • Implement smart retry mechanism to improve request success rate
  • Enhance user experience through error recovery strategies
  • Unified error handling simplifies code maintenance

Key Points

  • Distinguish between network errors, response errors, and configuration errors
  • Reasonable retry strategies avoid excessive requests
  • Error recovery mechanisms provide fallback options
  • User-friendly error messages improve experience