Spring Boot REST API에서 예외 처리를 표준화하는 방법을 정리해 드립니다. @ExceptionHandler와 @RestControllerAdvice 활용법부터 Validation 예외, 커스텀 예외, 공통 응답 구조까지 실무 중심으로 자세히 알아보시기 바랍니다.

REST API를 개발하다 보면 다양한 예외 상황을 반드시 고려해야 합니다. 잘 설계된 API는 단순히 정상 응답만 제공하는 것이 아니라, 오류가 발생했을 때도 일관된 형식으로 오류 정보를 반환합니다.
Spring Boot에서는 @ExceptionHandler, @RestControllerAdvice, @ResponseStatus 등을 활용하여 예외 처리를 표준화할 수 있습니다. 이번 글에서는 실무에서 많이 사용하는 Spring Boot REST API 예외 처리 방법을 단계별로 정리해 드리겠습니다.
01. REST API에서 예외 처리가 중요한 이유
REST API의 신뢰성을 높이기 위해 반드시 고려해야 하는 핵심 요소를 살펴보겠습니다.
사용자는 정상적인 요청만 보내지 않습니다. 잘못된 입력값을 전달하거나 존재하지 않는 데이터를 조회하는 경우도 많습니다.
예외 처리를 하지 않으면 서버 내부 오류 화면이나 스택 트레이스가 그대로 노출될 수 있으며, 클라이언트는 어떤 문제가 발생했는지 알기 어렵습니다.
✓ 확인할 점
좋은 REST API의 예외 처리는 다음과 같은 특징을 갖습니다.
- HTTP 상태코드를 올바르게 사용합니다.
- 오류 응답 형식을 항상 동일하게 유지합니다.
- 민감한 내부 정보를 노출하지 않습니다.
- 클라이언트가 오류 원인을 쉽게 파악할 수 있도록 합니다.
예를 들어 다음과 같은 형태가 일반적으로 많이 사용됩니다.
항목예시
| status | 404 |
| error | NOT_FOUND |
| message | 회원을 찾을 수 없습니다. |
| path | /api/users/10 |
02. @ExceptionHandler의 역할
특정 예외를 개별적으로 처리하는 방법을 알아보겠습니다.
Spring Boot에서는 @ExceptionHandler를 이용하여 원하는 예외를 직접 처리할 수 있습니다.
예를 들어 IllegalArgumentException이 발생하면 해당 예외만 별도로 처리하여 원하는 응답을 반환할 수 있습니다.
✓ 기본 동작
컨트롤러 내부에서 발생한 예외를 가로채서 처리합니다.
대표적으로 다음과 같은 예외를 처리할 수 있습니다.
- IllegalArgumentException
- IllegalStateException
- RuntimeException
- CustomException
- MethodArgumentNotValidException
특정 컨트롤러에서만 사용하는 예외라면 @ExceptionHandler만으로도 충분한 경우가 많습니다.
03. @RestControllerAdvice를 사용하는 이유
프로젝트 전체의 예외 처리를 하나로 통합하는 방법을 설명드립니다.
실무에서는 컨트롤러마다 예외 처리 코드를 작성하지 않습니다.
대부분 @RestControllerAdvice를 이용하여 공통 예외 처리를 구현합니다.
✓ 장점
- 중복 코드가 크게 줄어듭니다.
- 모든 API가 동일한 오류 형식을 사용합니다.
- 유지보수가 쉬워집니다.
- 새로운 예외를 추가하기 편리합니다.
특히 프로젝트 규모가 커질수록 전역 예외 처리의 중요성은 더욱 커집니다.

04. Validation 예외 처리
입력값 검증에서 자주 발생하는 예외를 살펴보겠습니다.
Spring Boot에서는 @Valid와 Validation을 함께 사용하는 경우가 많습니다.
예를 들어 다음과 같은 검증이 가능합니다.
- 이름은 필수입니다.
- 이메일 형식이어야 합니다.
- 비밀번호는 최소 길이를 만족해야 합니다.
검증에 실패하면 일반적으로 MethodArgumentNotValidException이 발생합니다.
✓ 실무 처리 방법
Validation 오류는 하나의 메시지만 반환하기보다 모든 오류를 함께 전달하는 경우가 많습니다.
예를 들어 다음과 같은 정보를 응답에 포함할 수 있습니다.
- 필드명
- 오류 메시지
- 입력값
- 오류 코드
이러한 방식은 프론트엔드에서 사용자에게 정확한 오류를 안내하는 데 도움이 됩니다.
05. 커스텀 예외(Custom Exception) 활용
비즈니스 로직에서는 직접 정의한 예외를 사용하는 것이 좋습니다.
회원 조회를 예로 들면 다음과 같은 예외를 만들 수 있습니다.
- UserNotFoundException
- DuplicateEmailException
- InvalidTokenException
- OrderNotFoundException
✓ 장점
RuntimeException만 사용하는 것보다 의미가 명확해집니다.
예를 들어
- 회원이 존재하지 않습니다.
- 이미 가입된 이메일입니다.
- 주문 정보를 찾을 수 없습니다.
처럼 상황별 예외를 구분할 수 있어 유지보수가 쉬워집니다.
06. HTTP 상태코드 선택 기준
예외와 상태코드를 올바르게 연결하는 것이 중요합니다.
✓ 자주 사용하는 상태코드
상태코드의미사용 사례
| 400 | Bad Request | 요청값 오류 |
| 401 | Unauthorized | 인증 실패 |
| 403 | Forbidden | 권한 부족 |
| 404 | Not Found | 데이터 없음 |
| 409 | Conflict | 중복 데이터 |
| 422 | Unprocessable Entity | 검증 실패 정책에 따라 사용 가능 |
| 500 | Internal Server Error | 서버 오류 |
상태코드는 프로젝트 정책에 따라 일부 차이가 있을 수 있지만, 일관성 있게 사용하는 것이 가장 중요합니다.
07. 공통 오류 응답(Response DTO) 설계
모든 API에서 동일한 응답 형식을 사용하는 것이 좋습니다.
✓ 추천 구성
다음과 같은 항목을 포함하면 관리하기 편리합니다.
- status
- error
- message
- timestamp
- path
필요에 따라 다음 정보를 추가하기도 합니다.
- errorCode
- validationErrors
- traceId
- requestId
클라이언트는 항상 동일한 JSON 구조를 받을 수 있으므로 오류 처리 로직도 단순해집니다.
08. 실무에서 많이 사용하는 예외 처리 구조
실무 프로젝트에서는 계층별 역할을 명확하게 구분하는 경우가 많습니다.
✓ 권장 구조
- Controller
- Service
- Repository
- Exception
- GlobalExceptionHandler
- ErrorResponse
Service에서는 비즈니스 예외를 발생시키고, GlobalExceptionHandler에서 이를 받아 공통 응답으로 변환하는 구조가 많이 사용됩니다.
이처럼 역할을 분리하면 테스트도 쉬워지고 프로젝트 규모가 커져도 관리하기 편리합니다.
09. 예외 처리 시 주의해야 할 사항
실무에서 자주 발생하는 실수를 함께 알아보겠습니다.
✓ 피해야 할 사례
- 모든 예외를 Exception 하나로 처리합니다.
- 항상 500 상태코드만 반환합니다.
- 내부 스택 트레이스를 그대로 노출합니다.
- 데이터베이스 오류를 사용자에게 그대로 보여줍니다.
- 오류 응답 형식이 API마다 다릅니다.
✓ 권장 사항
- 예외를 목적에 맞게 분리합니다.
- 공통 응답 형식을 유지합니다.
- 로그와 사용자 메시지를 구분합니다.
- 사용자에게는 이해하기 쉬운 메시지를 제공합니다.
- 서버 로그에는 디버깅에 필요한 상세 정보를 남깁니다.
10. 마무리
Spring Boot REST API에서는 예외 처리가 API 품질을 결정하는 중요한 요소입니다.
작은 프로젝트에서는 @ExceptionHandler만으로도 충분할 수 있지만, 규모가 커질수록 @RestControllerAdvice를 활용한 전역 예외 처리 구조가 유지보수성과 확장성 측면에서 훨씬 유리합니다.
또한 Validation 예외, 커스텀 예외, HTTP 상태코드, 공통 오류 응답 구조를 함께 설계하면 프론트엔드와의 연동도 훨씬 수월해집니다.
프로젝트 초기에 일관된 예외 처리 정책을 마련해 두면 이후 기능이 추가되더라도 안정적인 REST API를 운영하는 데 큰 도움이 됩니다.
FAQ
Q1. @ExceptionHandler와 @RestControllerAdvice의 차이는 무엇인가요?
@ExceptionHandler는 특정 컨트롤러에서 발생한 예외를 처리하는 데 적합하며, @RestControllerAdvice는 여러 컨트롤러에서 발생하는 예외를 전역으로 처리하는 데 적합합니다.
Q2. RuntimeException만 사용해도 되나요?
가능하지만 권장되지는 않습니다. 의미 있는 커스텀 예외를 정의하면 코드의 가독성과 유지보수성이 크게 향상됩니다.
Q3. Validation 오류는 어떻게 처리하는 것이 좋나요?
MethodArgumentNotValidException을 전역에서 처리하여 필드명과 오류 메시지를 함께 반환하는 방식이 많이 사용됩니다.
Q4. REST API에서 500 오류는 언제 반환해야 하나요?
예상하지 못한 서버 내부 오류가 발생했을 때 사용하는 것이 적절합니다. 입력값 오류나 데이터 조회 실패는 각각 400 또는 404 등의 상태코드를 사용하는 것이 일반적입니다.
Q5. 공통 오류 응답 DTO는 꼭 만들어야 하나요?
필수는 아니지만 실무에서는 거의 대부분 공통 오류 응답 객체를 사용합니다. API 응답 형식이 일관되어 유지보수와 프론트엔드 개발이 훨씬 수월해집니다.
'실무개발' 카테고리의 다른 글
| HTTP 요청 메서드 GET POST PUT PATCH DELETE 차이점 완벽 정리 (0) | 2026.07.19 |
|---|---|
| REST API HTTP 상태 코드 제대로 사용하는 방법 (0) | 2026.07.17 |
| JSON 응답 구조 표준화하는 방법과 API 설계 팁 (1) | 2026.07.17 |
| REST API 응답 형식 ResponseEntity 사용법 총정리 (0) | 2026.07.16 |
| Spring Boot DTO 설계 시 꼭 알아야 하는 작성 원칙 (0) | 2026.07.15 |
