postController
postService
GlobalExceptionHandler.java
@ExceptionHandler(NotFoundException.class)
public ResponseEntity notFoundHandler(NotFoundException e) {
log.error("notFoundHandler : {}", e.getMessage());
return new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_FOUND);
}
https://tecoble.techcourse.co.kr/post/2020-08-17-custom-exception/
스택트레이스란?
스택트레이스는 프로그램이 시작된 시점부터 현재 위치 까지의 메서드 호출 목록입니다. 이는 예외가 어디서 발생했는지 알려주기 위해 JVM이 자동으로 생성합니다.
스택트레이스는 에러가 발생된 시점부터 프로그램이 시작된 시점까지 거슬러 올라가면서 출력하기 때문에 먼저 실행 된 메서드가 아래쪽에 위치합니다.
이런 로그를 접하면 겁부터 먹고, 읽으려 들지 않습니다. 하지만 에러의 진정한 원인은 가장 아래쪽 에 있는 Caused by:로 시작되는 줄부터 아래로 세 줄이면 충분합니다.
이 중 에러가 발생한 곳은 "at..."으로 시작하는 첫 번째 메시지입니다. 해당 메서드를 호출한 직후에 에러가 발생한 것입니다(역순이기 때문). 두 번째 줄은 「 'com.mycompany.service.impl.PortalManagerImpl' 클래스의 'deleteMenuItem' 메서드를 호출할 때 603번 째 줄에서 NullPointerException이 발생했습니다. 」라는 뜻입니다.
stack trace 성능에 영향을 미친다.
stack trace는 예외 발생 시 call stack에 있는 메소드 리스트를 저장한다. 이를 통해 예외가 발생한 정확한 위치를 파악할 수 있다. 하지만 try/catch나 Advice를 통해 예외를 처리한다면 해당 예외의 stack trace는 사용하지 않을 때가 많다. 비용을 들여 만들었지만 사용하지 않고 사라지는 형태. 너무나도 비효율적이다.
Custom Exception은 값을 검사해 하위 비지니스 로직을 수행할 수 없어 이를 방지하기 위한 용도로 만들었기 때문에 사실 현재 값이 어떤 call stack을 가지는지에 대한 trace는 필요하지 않았습니다.
exception stack trace는 Throwable.fillInStackTrace 메소드를 통해 생성되므로 이를 아무런 trace도 가지지 않게 Override해둘 수 있습니다.
@Getter
@AllArgsConstructor
public class CustomException extends RuntimeException {
private final ErrorCode errorCode;
@Override
public synchronized Throwable fillInStackTrace() {
return this;
}
}
stack trace를 가지지 않도록 Overriding 해둔 Exception이라면 static final 로 선언하고 일종의 상수 값 형태로 예외를 캐싱해두고 쓰는것이 매번 new로 생성하는 것보다 효율적입니다.
public class CustomException extends RuntimeException {
public static final CustomException INVALID_NICKNAME = new CustomException(ResponseType.INVALID_NICKNAME);
public static final CustomException INVALID_PARAMETER = new CustomException(ResponseType.INVALID_PARAMETER);
public static final CustomException INVALID_TOKEN = new CustomException(ResponseType.INVALID_TOKEN);
//생략
}
Exception 클래스에 예외 상황에 대한 적당한 응답 메세지나 코드를 담도록 한 뒤 예외 발생 상황에서 new 키워드 없이 throw 합니다.
if (StringUtils.isBlank(parameter)) {
throw WebtoonCoreException.INVALID_PARAMETER;
}
참고자료
https://jaehoney.tistory.com/51
https://thswave.github.io/java/exception/2015/06/28/exceptions-are-bad.html