Spring: CustomException vs 구체적 예외 클래스

임채령·2024년 10월 15일

이전에 포스팅 했듯이 보통 일관된 예외처리 및 응답처리를 한다.

에러 처리에 대한 구현을 여러번 하다보니 문득 생각이 들었다.

CustomException 이라는 클래스를 둬서 하나의 클래스로 처리해도 되지않을까 ? 그래서 찾아보고 장단점을 비교해서 표로 정리해보았다 !!

CustomException 하나로 처리했을 때 vs 구체적으로 나눴을 때의 장단점

구분CustomException구체적인 예외 클래스
단순성- 코드가 단순하고 예외 처리가 일관적- 예외 처리 로직이 명확
중복 코드- 예외를 하나의 클래스에서 관리하므로 적은 중복 코드- 여러 예외 클래스에서 중복된 코드를 제거하기 위해 상속 구조 사용 가능
개발 속도- 빠른 초기 개발- 처계적인 예외 관리
유지보수성- 유지보수에 용이- 각 예외가 독립적이므로 관리 용이
확장성 부족- 예외가 복잡해질수록 CustomException 클래스에 많은 조건이 추가되어 복잡- 예외가 늘어날수록 많은 클래스 파일이 생기며, 관리해야 할 파일이 많아짐
가독성 저하- 모든 예외를 한 클래스에서 처리하면 어떤 예외가 발생했는지 직관적으로 보기 어려움- 각 예외의 의미가 명확하게 드러나므로 높은 코드 가독성
세분화- 특정 예외마다 다른 처리가 필요할 경우 커스텀 로직 추가가 복잡해질 수 있음- 각 예외에 대해 필요한 로직을 구체적으로 구현할 수 있움
에러 구분의 어려움- 예외가 모두 동일한 타입으로 처리되므로, 로직이 복잡해지면 어떤 예외인지 구분하기 어려움- 예외 클래스마다 의미가 분명하므로, 어디서 어떤 예외가 발생했는지 쉽게 알 수 있음
특정 예외 처리- 특정 예외에 대해 추가 로직을 넣기가 어려움- 각 예외별로 처리 로직을 쉽게 구현할 수 있음

이렇게 정리해보았는데 시스템의 완성도를 중요시하는 나에게는 구체적으로 예외를 처리하는게 맘에 쏙 든다 !!

그래서 구체적으로 예외를 처리하는데 크게 예외 클래스를 만들고 ErrorCode 클래스를 통해 Enum 타입으로 더 자세하게 관리하려한다 ! 그래서 이번 포스팅은 크게 쪼갠 예외 클래스들이다 !!

1. BadRequestException (400 - Bad Request)

  • 클라이언트가 잘못된 요청을 했을 때 발생하는 예외
    • 필수 파라미터가 누락되었을 때
    • 요청 데이터가 유효하지 않을 때 (형식이 맞지 않거나 값이 잘못된 경우)
    • 잘못된 쿼리 파라미터 또는 경로 파라미터
public class BadRequestException extends CustomException {
    public BadRequestException(String message) {
        super(ErrorCode.INVALID_REQUEST_ARGUMENT);
    }
}

2. UnauthorizedException (401 - Unauthorized)

  • 인증되지 않은 사용자가 리소스에 접근하려 할 때 발생하는 예외
    • JWT 토큰이 유효하지 않거나 만료되었을 때
    • 인증 정보가 누락되었을 때
    • 로그인되지 않은 사용자가 리소스에 접근하려 할 때
public class UnauthorizedException extends CustomException {
    public UnauthorizedException(String message) {
        super(ErrorCode.UNAUTHORIZED_ACCESS);
    }
}

3. ForbiddenException (403 - Forbidden)

  • 인증된 사용자가 해당 리소스에 접근할 권한이 없을 때 발생하는 예외
    • 관리자가 아닌 사용자가 관리자 페이지에 접근할 때
    • 특정 리소스에 대한 접근 권한이 없는 경우
public class ForbiddenException extends CustomException {
    public ForbiddenException(String message) {
        super(ErrorCode.FORBIDDEN_ACCESS);
    }
}

4. NotFoundException (404 - Not Found)

  • 요청한 리소스를 찾을 수 없을 때 발생하는 예외
    • 요청한 데이터가 데이터베이스에 존재하지 않을 때
    • 잘못된 경로로 요청했을 때
    • 특정 사용자나 리소스를 찾을 수 없을 때
public class NotFoundException extends CustomException {
    public NotFoundException(String message) {
        super(ErrorCode.RESOURCE_NOT_FOUND);
    }
}

5. ConflictException (409 - Conflict)

  • 리소스 상태가 중복되거나 충돌이 발생했을 때 발생하는 예외
    • 중복된 데이터가 있을 때
    • 리소스가 동시에 변경되어 충돌이 발생했을 때
public class ConflictException extends CustomException {
    public ConflictException(String message) {
        super(ErrorCode.DUPLICATED_VALUE);
    }
}

6. InternalServerErrorException (500 - Internal Server Error)

  • 서버 내부에서 예기치 않은 오류가 발생했을 때 발생하는 예외
    • 데이터베이스 연결 오류
    • 서버에서 처리할 수 없는 논리적인 오류
    • 기타 비즈니스 로직에서 발생한 예상치 못한 오류
public class InternalServerErrorException extends CustomException {
    public InternalServerErrorException(String message) {
        super(ErrorCode.INTERNAL_SERVER_ERROR);
    }
}

7. ServiceUnavailableException (503 - Service Unavailable)

  • 서버가 일시적으로 서비스를 제공할 수 없을 때 발생하는 예외
    • 서버가 과부하 상태일 때
    • 외부 API나 서드파티 서비스가 응답하지 않을 때
public class ServiceUnavailableException extends CustomException {
    public ServiceUnavailableException(String message) {
        super(ErrorCode.SERVICE_UNAVAILABLE);
    }
}

8. MethodNotAllowedException (405 - Method Not Allowed)

  • 요청된 HTTP 메서드가 지원되지 않을 때 발생하는 예외
    • POST 요청을 받지 않는 엔드포인트에 POST 요청을 했을 때
    • DELETE 메서드를 허용하지 않는 API에 DELETE 요청을 했을 때
public class MethodNotAllowedException extends CustomException {
    public MethodNotAllowedException(String message) {
        super(ErrorCode.METHOD_NOT_ALLOWED);
    }
}

0개의 댓글