상세 컨텐츠

본문 제목

공통 Exception 처리 / Exception Message 처리

Spring/Exception

by Chan.94 2022. 9. 14. 08:52

본문

반응형

기본적으로 알고 있는 방법은 Exception을 try ~ catch로 처리하는 방법일 것이다.

try ~ catch를 사용하지 않고 Exception을 컨트롤할 수 있다.

 

사용되는 어노테이션

어노테이션 설명
@ControllerAdvice @Controller 즉, 웹 어플리케이션 전역에서 발생할 수 있는 예외를 잡아 처리해주는 annotation이다.
@RestControllerAdvice @ControllerAdvice 어노테이션과 동일한 역할을 수행하고 추가적으로  @ResponseBody를 통해 객체를 리턴할 수 있다.
@ExceptionHandler 발생한 Exception 에 따라 선택적으로 특정 메소드를 실행한다.

 

주의사항

@Controller, @RestController에만 적용 가능하다. (@Service 같은 Bean에서는 안된다.)


CustomException

public class CommonMessageException extends RuntimeException{
	private String errorCode = "";
	private String errorMessageParam = "";
	private Exception exception; //try ~ catch 구문에서 catch한 예외를 담을때 사용
	
	public CommonMessageException() {
		this.errorCode = CommonMessageEnum.ERROR0000.getErrorCode();
	}
    
	public CommonMessageException(String errorCode) {
		this.errorCode = errorCode;
	}

	public CommonMessageException(Exception exception) {
		this.exception = exception;
	}

	public Exception getException() {
		return exception;
	}

	public String getErrorCode() {
		return errorCode;
	}
	
	public String getErrorMessageParam() {
		return errorMessageParam;
	}

}

CommonMessageException은 RuntimeException을 상속받고 있다.

RuntimeException을 상속받는 이유는 @Transactional은 default 속성 값으로 unChecked Exception과 Error에 대해서만 rollback을 진행하기 때문이다. 

해당 부분의 내용을 모른다면 checked / UnChecked Exception / @Transactional rollback 포스팅을 참고바란다.

 

ExceptionHandler

@RestControllerAdvice
public class CommonExceptionHandler {
	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	@ExceptionHandler(CommonMessageException.class)
	public void error(CommonMessageException e){
		if(e.getException() != null) {	//try ~ catch에서 catch한 Exception 내용 출력
			e.getException().printStackTrace();
		}else {
			
			for(CommonMessageEnum commonMessageEnum : CommonMessageEnum.values()) {
				if(commonMessageEnum.getErrorCode().equals(e.getErrorCode())) {
					logger.debug("CommonMessageCode : " + e.getErrorCode() 
							+ " [" + CommonMessageEnum.valueOf(e.getErrorCode()).getErrorMessage()  + "]");
					break;
				}
			}
			
			e.printStackTrace();
		}
		
	}
	
	@ExceptionHandler(Exception.class)
	public void error(Exception e) throws Exception{
		e.printStackTrace();
	}
	
}

@ExceptionHandler를 통해 발생되는 Exception을 분리하고 실행되어야 하는 코드를 공통화시킬 수 있다.

CommonMessageException 클래스는 개발자가 throw 하는 Exception으로 사용할 것이다.

(CommonMessageException은 RuntimeException을 상속받고 있다.)

 

Exception 클래스는 개발자가 예상하지 못한 에러가 발생하였을 경우 처리하기 위해 사용할 것이다.

 

코드에는 return 하는 부분은 제외하였지만 @RestControllerAdvice를 선언하였기 때문에 JSON, XML 형식으로 화면으로 값을 반환할 수 있다.

 

CommonMessageException의 Exception 멤버의 null 유무로 try ~ catch에서 catch 한 Exception인지를 구분한다.

try ~ catch에서 catch 한 Exception을 구분하는 이유는 checked Exception의 경우 트랜잭션 관리를 직접 해야 하는데 catch부분에서 CommonMessageException을 throw 함으로써 rollback이 진행되도록 하기 위함이다.

 

해당 부분은 필자의 주관적인 관점에서 작성한 부분이기 때문에 개념에 대해서 접근하는 사람은 넘어가도 좋다.

 

Message

public enum CommonMessageEnum {
	ERROR0000("ERROR0000", "관리자에게 문의 바랍니다."),
	ERROR0001("ERROR0001", "중복 데이터가 존재합니다."),
	;
	
	private final String errorCode;
	private final String errorMessage;
	
	CommonMessageEnum(String errorCode, String errorMessage) {
		this.errorCode = errorCode;
		this.errorMessage = errorMessage;
	}
	
	public String getErrorCode() {
		return errorCode;
	}
	public String getErrorMessage() {
		return errorMessage;
	}
	
}

메시지를 간단하게 Enum으로 구성하여 사용하도록 하였다.

XML 또는 DB로 관리하여 서버가 올라갈 때 또는 로그인이 진행될 때 메모리에 올려서 사용하여도 무방하다.

 

간단한 테스트를 위해 Enum으로 작성하였지만 Spring에서 제공하는 MessageSource 라이브러리를 사용하면 message를 더 스마트하고 효율적으로 관리할 수 있다. 

MessageSource에 관한 내용은 메세지 다국어 처리 / 공통 Message 처리 (MessageSource) 확인 바란다.

반응형

'Spring > Exception' 카테고리의 다른 글

checked / UnChecked Exception / @Transactional rollback  (0) 2022.09.13

관련글 더보기

댓글 영역

>