
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
package com.takensoft.common.exception;
import com.takensoft.common.message.MessageCode;
import com.takensoft.common.util.ResponseUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException;
import org.springframework.dao.DataAccessException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.resource.NoResourceFoundException;
import java.net.UnknownHostException;
/**
* @author takensoft
* @since 2025.01.22
* @modification
* since | author | description
* 2025.01.22 | takensoft | 최초 등록
* 2025.03.12 | 하석형 | handleCustomCodeDuplicationException, handleCustomDataDuplicationException 추가
* 2025.03.21 | 하석형 | handleFileSizeLimitExceededException, handleCustomFileUploadFailException, handleCustomPrhibtWordException 추가
*
* 스프링 MVC 컨트롤러에서 발생하는 예외를 처리하는 공통 클래스
*/
@RestControllerAdvice
@Slf4j
@RequiredArgsConstructor
public class GlobalExceptionHandler {
private final ResponseUtil resUtil;
/**
* @param e - 처리할 예외 객체
*
* 예외를 로그로 출력
*/
private void logError(Exception e) {
StackTraceElement[] stackTrace = e.getStackTrace();
if(stackTrace.length > 0) {
StackTraceElement origin = stackTrace[0]; // 예외가 발생한 첫 번째 위치
log.error("[ {} ] - {} ({} [{}]번째 행)",
e.getClass().getSimpleName(),
e.getMessage(),
origin.getFileName(),
origin.getLineNumber()
);
} else {
log.error("[ {} ] - {}", e.getClass().getSimpleName(), e.getMessage());
}
e.printStackTrace();
}
/**
* @param dae - DataAccessException 예외 객체
* @return 유효성 검사 실패에 대한 HTTP 응답
*
* SQL 예외 처리
*/
@ExceptionHandler(DataAccessException.class)
public ResponseEntity<?> handleDataAccessException(DataAccessException dae) {
logError(dae);
// String msg = dae.getMessage().toLowerCase();
// if(msg.contains("null value")) {
// return resUtil.errorRes(MessageCode.SQL_NULL_VALUE);
// } else if(msg.contains("duplicate key")) {
// return resUtil.errorRes(MessageCode.SQL_DUPLICATE_KEY);
// }
return resUtil.errorRes(MessageCode.COMMON_UNKNOWN_ERROR);
}
/**
* @param mave - MethodArgumentNotValidException 예외 객체
* @return 유효성 검사 실패에 대한 HTTP 응답
*
* 유효성 검증에 실패한 경우
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<?> handleValidationException(MethodArgumentNotValidException mave) {
logError(mave);
String message = mave.getBindingResult().getFieldErrors().stream()
.findFirst()
.map(error -> error.getDefaultMessage())
.orElse("유효성 검증에 실패했습니다.");
return resUtil.errorRes(HttpStatus.BAD_REQUEST, message);
}
/**
* @param ne - NullPointerException 예외 객체
* @return NullPointerException에 대한 HTTP 응답
*
* NullPointerException이 발생한 경우
*/
@ExceptionHandler(NullPointerException.class)
public ResponseEntity<?> handleNullPointerException(NullPointerException ne) {
logError(ne);
return resUtil.errorRes(MessageCode.COMMON_NULL_POINT);
}
/**
* @param ie - IllegalArgumentException 예외 객체
* @return IllegalArgumentException에 대한 HTTP 응답
*
* IllegalArgumentException이 발생한 경우
*/
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<?> handleIllegalArgumentException(IllegalArgumentException ie) {
logError(ie);
return resUtil.errorRes(MessageCode.COMMON_ILLEGAL_ARGUMENT);
}
/**
* @param nrfe - NoResourceFoundException 예외 객체
* @return NoResourceFoundException에 대한 HTTP 응답
*
* NoResourceFoundException이 발생한 경우
*/
@ExceptionHandler(NoResourceFoundException.class)
public ResponseEntity<?> handleNoResourceFoundException(NoResourceFoundException nrfe) {
logError(nrfe);
return resUtil.errorRes(MessageCode.COMMON_BAD_REQUEST);
}
/**
* @param hrmnse - HttpRequestMethodNotSupportedException 예외 객체
* @return HttpRequestMethodNotSupportedException에 대한 HTTP 응답
*
* HttpRequestMethodNotSupportedException이 발생한 경우
*/
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public ResponseEntity<?> handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException hrmnse) {
logError(hrmnse);
return resUtil.errorRes(MessageCode.COMMON_METHOD_NOT_ALLOWED);
}
/**
* @param cite - CustomIdTakenException 예외 객체
* @return CustomIdTakenException에 대한 HTTP 응답
*
* CustomIdTakenException이 발생한 경우
*/
@ExceptionHandler(CustomIdTakenException.class)
public ResponseEntity<?> handleCustomIdTakenException(CustomIdTakenException cite) {
logError(cite);
return resUtil.errorRes(MessageCode.SIGNUP_ID_TAKEN);
}
/**
* @param cbre - CustomBadRequestException 예외 객체
* @return CustomBadRequestException에 대한 HTTP 응답
*
* CustomBadRequestException이 발생한 경우
*/
@ExceptionHandler(CustomBadRequestException.class)
public ResponseEntity<?> handleCustomBadRequestException(CustomBadRequestException cbre) {
logError(cbre);
return resUtil.errorRes(MessageCode.COMMON_BAD_REQUEST);
}
/**
* @param cade - CustomAccessDeniedException 예외 객체
* @return CustomAccessDeniedException에 대한 HTTP 응답
*
* CustomAccessDeniedException이 발생한 경우
*/
@ExceptionHandler(CustomAccessDeniedException.class)
public ResponseEntity<?> handleCustomAccessDeniedException(CustomAccessDeniedException cade) {
logError(cade);
return resUtil.errorRes(MessageCode.ACCESS_DENIED);
}
/**
* @param cpce - CustomPasswordComparisonException 예외 객체
* @return CustomPasswordComparisonException에 대한 HTTP 응답
*
* CustomPasswordComparisonException이 발생한 경우
*/
@ExceptionHandler(CustomPasswordComparisonException.class)
public ResponseEntity<?> handleCustomPasswordComparisonException(CustomPasswordComparisonException cpce) {
logError(cpce);
return resUtil.errorRes(MessageCode.LOGIN_INVALID_CREDENTIALS);
}
/**
* @param cfe - CustomNotFoundException 예외 객체
* @return CustomNotFoundException에 대한 HTTP 응답
*
* CustomNotFoundException이 발생한 경우
*/
@ExceptionHandler(CustomNotFoundException.class)
public ResponseEntity<?> handleNotFoundException(CustomNotFoundException cfe) {
logError(cfe);
return resUtil.errorRes(MessageCode.COMMON_NOT_FOUND);
}
/**
* @param cife - CustomInsertFailException 예외 객체
* @return CustomInsertFailException에 대한 HTTP 응답
*
* CustomInsertFailException이 발생한 경우
*/
@ExceptionHandler(CustomInsertFailException.class)
public ResponseEntity<?> handleCustomInsertFailException(CustomInsertFailException cife) {
logError(cife);
return resUtil.errorRes(MessageCode.COMMON_INSERT_FAIL);
}
/**
* @param cufe - CustomUpdateFailException 예외 객체
* @return CustomUpdateFailException에 대한 HTTP 응답
*
* CustomUpdateFailException이 발생한 경우
*/
@ExceptionHandler(CustomUpdateFailException.class)
public ResponseEntity<?> handleCustomUpdateFailException(CustomUpdateFailException cufe) {
logError(cufe);
return resUtil.errorRes(MessageCode.COMMON_UPDATE_FAIL);
}
/**
* @param cdfe - CustomDeleteFailException 예외 객체
* @return CustomDeleteFailException에 대한 HTTP 응답
*
* CustomDeleteFailException이 발생한 경우
*/
@ExceptionHandler(CustomDeleteFailException.class)
public ResponseEntity<?> handleCustomDeleteFailException(CustomDeleteFailException cdfe) {
logError(cdfe);
return resUtil.errorRes(MessageCode.COMMON_DELETE_FAIL);
}
/**
* @param ukhe - UnknownHostException 예외 객체
* @return UnknownHostException에 대한 HTTP 응답
*
* UnknownHostException이 발생한 경우
*/
@ExceptionHandler(UnknownHostException.class)
public ResponseEntity<?> handleUnknownHostException(UnknownHostException ukhe) {
logError(ukhe);
return resUtil.errorRes(MessageCode.NETWORK_UNKNOWN_HOST);
}
/**
* @param ccde - CustomCodeDuplicationException 예외 객체
* @return CustomCodeDuplicationException에 대한 HTTP 응답
*
* CustomCodeDuplicationException이 발생한 경우
*/
@ExceptionHandler(CustomCodeDuplicationException.class)
public ResponseEntity<?> handleCustomCodeDuplicationException(CustomCodeDuplicationException ccde) {
logError(ccde);
return resUtil.errorRes(MessageCode.COMMON_DUPLICATION_CODE);
}
/**
* @param cdde - CustomDataDuplicationException 예외 객체
* @return CustomDataDuplicationException에 대한 HTTP 응답
*
* CustomDataDuplicationException이 발생한 경우
*/
@ExceptionHandler(CustomDataDuplicationException.class)
public ResponseEntity<?> handleCustomDataDuplicationException(CustomDataDuplicationException cdde) {
logError(cdde);
// CustomDataDuplicationException의 커스텀 메시지가 "Y"인 경우
if(cdde.getCustom().equals("Y")) {
return resUtil.errorRes(HttpStatus.INTERNAL_SERVER_ERROR, cdde.getMessage());
} else {
return resUtil.errorRes(MessageCode.COMMON_DUPLICATION_DATA);
}
}
/**
* @param fsle - FileSizeLimitExceededException 예외 객체
* @return FileSizeLimitExceededException에 대한 HTTP 응답
*
* FileSizeLimitExceededException이 발생한 경우
*/
@ExceptionHandler(FileSizeLimitExceededException.class)
public ResponseEntity<?> handleFileSizeLimitExceededException(FileSizeLimitExceededException fsle) {
logError(fsle);
return resUtil.errorRes(MessageCode.COMMON_PAYLOAD_TOO_LARGE);
}
/**
* @param cfufe - CustomFileUploadFailException 예외 객체
* @return CustomFileUploadFailException에 대한 HTTP 응답
*
* CustomFileUploadFailException이 발생한 경우
*/
@ExceptionHandler(CustomFileUploadFailException.class)
public ResponseEntity<?> handleCustomFileUploadFailException(CustomFileUploadFailException cfufe) {
logError(cfufe);
return resUtil.errorRes(MessageCode.FILE_UPLOAD_FAIL);
}
/**
* @param cpwe - CustomPrhibtWordException 예외 객체
* @return CustomPrhibtWordException에 대한 HTTP 응답
*
* CustomPrhibtWordException이 발생한 경우
*/
@ExceptionHandler(CustomPrhibtWordException.class)
public ResponseEntity<?> handleCustomPrhibtWordException(CustomPrhibtWordException cpwe) {
logError(cpwe);
return resUtil.errorRes(MessageCode.COMMON_PROHIBITION_WORD, "\n* " + cpwe.getWord());
}
/**
* @param cnce - CustomNoChangeException 예외 객체
* @return CustomNoChangeException에 대한 HTTP 응답
*
* CustomNoChangeException이 발생한 경우
*/
@ExceptionHandler(CustomNoChangeException.class)
public ResponseEntity<?> handleCustomInsertFailException(CustomNoChangeException cnce) {
logError(cnce);
return resUtil.errorRes(MessageCode.COMMON_NO_CHANGE);
}
/**
* @param cesfe - CustomEmailSendFailException 예외 객체
* @return CustomEmailSendFailException에 대한 HTTP 응답
*
* CustomEmailSendFailException이 발생한 경우
*/
@ExceptionHandler(CustomEmailSendFailException.class)
public ResponseEntity<?> handleCustomEmailSendFailException(CustomEmailSendFailException cesfe) {
logError(cesfe);
return resUtil.errorRes(MessageCode.EMAIL_SEND_FAIL);
}
/**
* @param cevee - CustomEmailVerifyExpireException 예외 객체
* @return CustomEmailVerifyExpireException에 대한 HTTP 응답
*
* CustomEmailVerifyExpireException이 발생한 경우
*/
@ExceptionHandler(CustomEmailVerifyExpireException.class)
public ResponseEntity<?> handleCustomEmailVerifyExpireException(CustomEmailVerifyExpireException cevee) {
logError(cevee);
return resUtil.errorRes(MessageCode.EMAIL_VERIFY_EXPIRED);
}
/**
* @param cevfe - CustomEmailVerifyFailException 예외 객체
* @return CustomEmailVerifyFailException에 대한 HTTP 응답
*
* CustomEmailVerifyFailException이 발생한 경우
*/
@ExceptionHandler(CustomEmailVerifyFailException.class)
public ResponseEntity<?> handleCustomEmailVerifyFailException(CustomEmailVerifyFailException cevfe) {
logError(cevfe);
return resUtil.errorRes(MessageCode.EMAIL_VERIFY_FAIL);
}
/**
* @param cecnme - CustomEmailCodeNotMatchException 예외 객체
* @return CustomEmailCodeNotMatchException에 대한 HTTP 응답
*
* CustomEmailCodeNotMatchException이 발생한 경우
*/
@ExceptionHandler(CustomEmailCodeNotMatchException.class)
public ResponseEntity<?> handleCustomEmailCodeNotMatchException(CustomEmailCodeNotMatchException cecnme) {
logError(cecnme);
return resUtil.errorRes(MessageCode.CODE_NOT_MATCH);
}
/**
* @param e - Exception 예외 객체
* @return 기타 예외에 대한 HTTP 응답
*
* 그 외 모든 예외가 발생한 경우
*/
@ExceptionHandler(Exception.class)
public ResponseEntity<?> handleException(Exception e) {
logError(e);
return resUtil.errorRes(MessageCode.COMMON_UNKNOWN_ERROR);
}
}