[JavaScript] 커스텀 에러 클래스를 통한 에러 구분 및 확장

커스텀 에러 클래스 정의하기

class AuthenticationError extends Error {
  constructor(message) {
    super(message);                 // 부모 클래스의 생성자 호출
    this.name = 'AuthenticationError'; // 에러 이름 설정
  }
}

// 사용 예시
try {
  throw new AuthenticationError('인증 실패: 유효하지 않은 토큰입니다.');
} catch (error) {
  console.error(error.name);    // 출력: AuthenticationError
  console.error(error.message); // 출력: 인증 실패: 유효하지 않은 토큰입니다.
  console.error(error.stack);   // 에러 발생 위치의 스택 트레이스
}
  • AuthenticationError 클래스는 Error를 상속받아 에러 메시지와 이름을 설정합니다.
  • 에러를 발생시킨 후 catch 블록에서 에러 정보를 출력할 수 있습니다.

에러 클래스 확장을 통한 세부 에러 정의

class AuthorizationError extends AuthenticationError {
  constructor(resource) {
    super(`접근 권한이 없습니다: ${resource}`);
    this.name = 'AuthorizationError';
    this.resource = resource;
  }
}

// 사용 예시
try {
  throw new AuthorizationError('/admin/dashboard');
} catch (error) {
  if (error instanceof AuthorizationError) {
    console.error(`권한 오류: ${error.message}`);
    console.error(`문제의 리소스: ${error.resource}`);
  } else {
    console.error('예상치 못한 에러 발생:', error);
  }
}
  • AuthorizationError는 AuthenticationError를 상속받아 구체적인 권한 에러를 나타냅니다.
  • 추가로 resource 프로퍼티를 만들어 어떤 리소스에 접근하려 했는지 정보를 제공합니다.

에러 감싸기(Wrapping)를 통한 상세 원인 전달

class NetworkError extends Error {
  constructor(message, statusCode, url) {
    super(message);
    this.name = 'NetworkError';
    this.statusCode = statusCode;
    this.url = url;
  }
}

async function fetchUserData(userId) {
  const url = `https://api.example.com/users/${userId}`;
  try {
    const response = await fetch(url);
    if (!response.ok) {
      throw new NetworkError('Failed to fetch user data', response.status, url);
    }
    return await response.json();
  } catch (error) {
    if (error instanceof NetworkError) {
      throw error; // 이미 NetworkError인 경우 그대로 전파
    } else {
      // 다른 종류의 에러를 NetworkError로 감싸기
      throw new NetworkError('An error occurred while fetching user data', 0, url, error);
    }
  }
}

// 사용 예시
async function displayUserProfile(userId) {
  try {
    const userData = await fetchUserData(userId);
    console.log('User profile:', userData);
  } catch (error) {
    if (error instanceof NetworkError) {
      console.error(`Network error (${error.statusCode}):`, error.message);
      console.error('Requested URL:', error.url);
    } else {
      console.error('Unexpected error:', error);
    }
  }
}

// 함수 실행
displayUserProfile(123);
  • NetworkError 클래스는 Error를 확장하여 네트워크 관련 에러를 표현합니다. 상태 코드와 URL 정보를 추가로 포함합니다.
  • fetchUserData 함수는 사용자 데이터를 가져오는 비동기 함수입니다. 네트워크 요청 중 발생하는 에러를 NetworkError로 감싸서 던집니다.
  • displayUserProfile 함수는 fetchUserData를 사용하여 사용자 프로필을 표시하려고 시도합니다. 발생한 에러를 적절히 처리합니다.
  • 에러 처리 시, instanceof를 사용하여 NetworkError인지 확인하고, 그에 따라 다른 처리를 합니다.