예외 (Exception) 와 에러 (Error)
# 예외
- 입력 값의 처리가 불가능하거나 참조된 값이 잘못된 경우 등 애플리케이션이 정상적으로 동작하지 못하는 상황을 의미
- 개발자가 직접 처리할 수 있는 것이므로 미리 코드 설계를 통해 처리할 수 있음
# 에러
- 에러는 주로 자바의 가상머신에서 발생
- 예외와 달리 애플리케이션 코드에서 처리할 수 있는 것이 거의 없음
- 대표적인 예로 메모리 부족, 스택 오버플로 등이 있음
BasicErrorController
- 스프링 부트의 기본 예외처리 Controller
- 별다른 설정을 하지 않았다면 예외가 발생했을 때 BasicErrorController로 예외처리 요청이 전달
- 예외 발생 시 요청 전달 흐름
WAS -> 필터 -> 서블릿 -> 인터셉터 -> 컨트롤러
-> 컨트롤러(예외발생) -> 인터셉터 -> 서블릿 -> 필터 -> WAS
-> WAS -> 필터 -> 서블릿 -> 인터셉터 -> 컨트롤러(BasicErrorController)
예외 클래스
# Checked Exception , Unchecked Exception
Checked Exception | Unchecked Exception | |
처리 여부 | 반드시 예외 처리 필요 | 명시적 처리를 강제하지 않음 |
확인 시점 | 컴파일 단계 | 실행 중 단계 |
대표적인 예외 클래스 | IOException SQLException |
RuntimeException NullPointException IllegalArgumentException IndexOutOfBoundException SystemException |
예외발생 시 트랜잭션 처리 | rollback 하지 않음 | rollback 함 |
예외 처리 방법
# 예외 복구
- 예외 상황을 파악해서 문제를 해결하는 방식
- 대표적인 방법 try/catch 구문
int a = 1;
String b = "a";
try {
system.out.println(a + Integer.parseInt(b));
} catch (NumberFormatException e){
b = "2";
system.out.println(a + Integer.parseInt(b));
}
// try 블록에는 예외가 발생할 수 있는 코드를 작성
// 대체로 외부라이브러를 사용하는 경우에는 try 블록을 사용하라는 IDE의 알람이 발생하지만
// 개발자가 직접 작성한 로직은 예외 상황을 예측해서 try 블록에 포함시켜야 함
// catch 블록을 통해 발생하는 예외 상황을 처리하는 내용을 작성
// catch 블록은 여러개 작성 가능
// 위의 경우 catch 블록을 순차적으로 거치면서 예외 유형과 매칭되는 블록을 찾아 예외 처리 동작을 수행
# 예외 처리 회피
- 예외가 발생한 시점에서 바로 처리하는 것이 아니라 예외가 발생한 메서드를 호출한 곳에서 에러 처리를 할 수 있게 전가하는 방식
- throw 키워드를 사용해 어떤 예외가 발생했는지 호출부에 내용을 전달할 수 있음
int a = 1;
String b = "a";
try {
system.out.println(a + Integer.parseInt(b));
} catch (NumberFormatException e){
throw new NumberFormatException("숫자가 아닙니다.");
}
# 예외 전환
- 앞의 두 방식을 적절하게 섞은 방식
- try/catch 방식을 사용하면서 catch 블록에서 throw 키워드를 사용해 다른 예외 타입으로 전달하는 방식
- CustomException 사용
@ControllerAdvice, @RestControllerAdvice
- 핸들러 클래스
- 전역 컨트롤러 예외 처리기를 정의하는데 사용
- 여러 컨트롤러에서 발생하는 예외를 한 곳에서 관리 가능
- 보통 예외 처리에 대한 로직을 담고 있는 클래스에 이 어노테이션을 붙임
@ControllerAdvice
→ 주로 Spring MVC 애플리케이션에서 발생하는 예외를 처리하는 데 사용
→ 요청에 대한 응답이 View 형태로 전달 (page 리턴)
@RestControllerAdvice
→ 주로 RESTful 웹 서비스에서 예외를 처리하는 데 사용
→ 요청에 대한 응답이 JSON 또는 XML 형태로 전달
@ControllerAdvice
public class GlobalExceptionHandler {
// 예외 처리 로직
}
@ExceptionHandler
- 특정 예외를 처리하는 메서드를 정의하는 데 사용
- '@(Rest)ControllerAdvice' 어노테이션이 붙은 클래스 내부에 작성
- 특정 예외가 발생 시 호출되어 예외를 처리, 적절한 응답을 반환
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception ex) {
// 예외 처리 로직
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("An error occurred: " + ex.getMessage());
}
}
커스텀 예외 클래스 (CustomException)
- 프로그래머가 특정한 예외 상황을 나타내기 위해 직접 정의한 예외 타입
- 기존의 자바 예외 클래스를 확장하거나, 자바 예외 클래스를 구현하여 새로운 예외를 정의
- 코드를 더욱 명확하고 유지보수하기 쉽게 만들 수 있음
커스텀 예외 클래스 생성 단계
1. Exception 클래스 상속 또는 Throwable 인터페이스 구현
- 기존의 자바 예외 클래스를 상속하거나, Throwable 인터페이스를 구현해야 함
- 대부분의 경우 Exception 클래스를 상속하여 커스텀 예외를 정의
public class CustomException extends Exception {
// 예외 클래스 내용
}
2. 생성자 정의
- 예외 클래스에는 보통 기본 생성자뿐만 아니라 예외 메시지를 받는 생성자도 정의
- 이를 통해 예외 발생 시 예외에 대한 상세한 정보를 포함할 수 있음
public class CustomException extends Exception {
public CustomException() {
super();
}
public CustomException(String message) {
super(message);
}
}
3. 예외 추가 정보 포함 (선택적)
- 경우에 따라 예외 객체에 추가 정보를 포함하여 예외를 보다 유용하게 만들 수 있음
- 예외를 발생시킨 상황이나 예외 처리에 필요한 정보를 추가할 때 유용
public class CustomException extends Exception {
private int errorCode;
public CustomException(String message, int errorCode) {
super(message);
this.errorCode = errorCode;
}
public int getErrorCode() {
return errorCode;
}
}
4. 예외 활용
public class Example {
public void someMethod() throws CustomException {
// 예외 상황 발생 시
throw new CustomException("Custom exception occurred", 500);
}
}
'프레임워크(Framework) > Spring Boot' 카테고리의 다른 글
[Spring Boot] YAML 파일 (49) | 2024.04.15 |
---|---|
[Spring Boot] Validation (유효성 검사) (49) | 2024.04.15 |
[Spring Boot] ResponseEntity (49) | 2024.04.15 |
[Spring Boot] 파라미터 전달 방식 (45) | 2024.04.15 |
[Spring Boot] 개요 (24) | 2024.04.05 |