로그인 실패 exception 처리, saveErrorLogData 오타 수정

This commit is contained in:
2025-12-08 11:34:55 +09:00
parent 55edeaf300
commit 603f510973
3 changed files with 214 additions and 179 deletions

View File

@@ -23,6 +23,7 @@ import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
@@ -44,197 +45,198 @@ public class GlobalExceptionHandler {
@ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY)
@ExceptionHandler(EntityNotFoundException.class)
public ApiResponseDto<String> handlerEntityNotFoundException(
EntityNotFoundException e, HttpServletRequest request) {
EntityNotFoundException e, HttpServletRequest request) {
log.warn("[EntityNotFoundException] resource :{} ", e.getMessage());
String codeName = "NOT_FOUND_DATA";
ErrorLogEntity errorLog =
saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf("UNPROCESSABLE_ENTITY"),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf("UNPROCESSABLE_ENTITY"),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("UNPROCESSABLE_ENTITY"),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("UNPROCESSABLE_ENTITY"),
errorLog.getId());
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(HttpMessageNotReadableException.class)
public ApiResponseDto<String> handleUnreadable(
HttpMessageNotReadableException e, HttpServletRequest request) {
HttpMessageNotReadableException e, HttpServletRequest request) {
log.warn("[HttpMessageNotReadableException] resource :{} ", e.getMessage());
String codeName = "BAD_REQUEST";
ErrorLogEntity errorLog =
saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
}
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(NoSuchElementException.class)
public ApiResponseDto<String> handlerNoSuchElementException(
NoSuchElementException e, HttpServletRequest request) {
NoSuchElementException e, HttpServletRequest request) {
log.warn("[NoSuchElementException] resource :{} ", e.getMessage());
String codeName = "NOT_FOUND_DATA";
ErrorLogEntity errorLog =
saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("NOT_FOUND"),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("NOT_FOUND"),
errorLog.getId());
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(IllegalArgumentException.class)
public ApiResponseDto<String> handlerIllegalArgumentException(
IllegalArgumentException e, HttpServletRequest request) {
IllegalArgumentException e, HttpServletRequest request) {
log.warn("[handlerIllegalArgumentException] resource :{} ", e.getMessage());
String codeName = "BAD_REQUEST";
ErrorLogEntity errorLog =
saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
}
@ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY)
@ExceptionHandler(DataIntegrityViolationException.class)
public ApiResponseDto<String> handlerDataIntegrityViolationException(
DataIntegrityViolationException e, HttpServletRequest request) {
DataIntegrityViolationException e, HttpServletRequest request) {
log.warn("[DataIntegrityViolationException] resource :{} ", e.getMessage());
String codeName = "DATA_INTEGRITY_ERROR";
ErrorLogEntity errorLog =
saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf("UNPROCESSABLE_ENTITY"),
ErrorLogDto.LogErrorLevel.CRITICAL,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf("UNPROCESSABLE_ENTITY"),
ErrorLogDto.LogErrorLevel.CRITICAL,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("UNPROCESSABLE_ENTITY"),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("UNPROCESSABLE_ENTITY"),
errorLog.getId());
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public ApiResponseDto<String> handlerMethodArgumentNotValidException(
MethodArgumentNotValidException e, HttpServletRequest request) {
MethodArgumentNotValidException e, HttpServletRequest request) {
log.warn("[MethodArgumentNotValidException] resource :{} ", e.getMessage());
String codeName = "BAD_REQUEST";
ErrorLogEntity errorLog =
saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
}
@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ExceptionHandler(AccessDeniedException.class)
public ApiResponseDto<String> handlerAccessDeniedException(
AccessDeniedException e, HttpServletRequest request) {
AccessDeniedException e, HttpServletRequest request) {
log.warn("[AccessDeniedException] resource :{} ", e.getMessage());
String codeName = "UNAUTHORIZED";
ErrorLogEntity errorLog =
saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.ERROR,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.ERROR,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
}
@ResponseStatus(HttpStatus.BAD_GATEWAY)
@ExceptionHandler(HttpServerErrorException.BadGateway.class)
public ApiResponseDto<String> handlerHttpServerErrorException(
HttpServerErrorException e, HttpServletRequest request) {
HttpServerErrorException e, HttpServletRequest request) {
log.warn("[HttpServerErrorException] resource :{} ", e.getMessage());
String codeName = "BAD_GATEWAY";
ErrorLogEntity errorLog =
saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.CRITICAL,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.CRITICAL,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
}
@ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY)
@ExceptionHandler(IllegalStateException.class)
public ApiResponseDto<String> handlerIllegalStateException(
IllegalStateException e, HttpServletRequest request) {
IllegalStateException e, HttpServletRequest request) {
log.warn("[IllegalStateException] resource :{} ", e.getMessage());
String codeName = "UNPROCESSABLE_ENTITY";
ErrorLogEntity errorLog =
saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MemberException.DuplicateMemberException.class)
public ApiResponseDto<String> handlerDuplicateMemberException(
MemberException.DuplicateMemberException e, HttpServletRequest request) {
MemberException.DuplicateMemberException e, HttpServletRequest request) {
log.warn("[DuplicateMemberException] resource :{} ", e.getMessage());
String codeName = "";
@@ -252,86 +254,115 @@ public class GlobalExceptionHandler {
}
ErrorLogEntity errorLog =
saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf("BAD_REQUEST"),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf("BAD_REQUEST"),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("BAD_REQUEST"),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("BAD_REQUEST"),
errorLog.getId());
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MemberException.MemberNotFoundException.class)
public ApiResponseDto<String> handlerMemberNotFoundException(
MemberException.MemberNotFoundException e, HttpServletRequest request) {
MemberException.MemberNotFoundException e, HttpServletRequest request) {
log.warn("[MemberNotFoundException] resource :{} ", e.getMessage());
String codeName = "NOT_FOUND_USER";
ErrorLogEntity errorLog =
saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf("BAD_REQUEST"),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf("BAD_REQUEST"),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("BAD_REQUEST"),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("BAD_REQUEST"),
errorLog.getId());
}
@ResponseStatus(HttpStatus.CONFLICT)
@ExceptionHandler(DuplicateKeyException.class)
public ApiResponseDto<String> handlerDuplicateKeyException(
DuplicateKeyException e, HttpServletRequest request) {
DuplicateKeyException e, HttpServletRequest request) {
log.warn("[DuplicateKeyException] resource :{} ", e.getMessage());
String codeName = "DUPLICATE_DATA";
ErrorLogEntity errorLog =
saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf("CONFLICT"),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf("CONFLICT"),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("CONFLICT"),
errorLog.getId());
}
@ExceptionHandler(BadCredentialsException.class)
public ResponseEntity<ApiResponseDto<String>> handleBadCredentials(
BadCredentialsException e, HttpServletRequest request
) {
log.warn("[BadCredentialsException] resource : {} ", e.getMessage());
String codeName = "UNAUTHORIZED";
ErrorLogEntity errorLog =
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.WARNING,
e.getStackTrace());
ApiResponseDto<String> body =
ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf("CONFLICT"),
HttpStatus.valueOf(codeName),
errorLog.getId());
return ResponseEntity
.status(HttpStatus.UNAUTHORIZED) // 🔥 여기서 401 지정
.body(body);
}
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(RuntimeException.class)
public ApiResponseDto<String> handlerRuntimeException(
RuntimeException e, HttpServletRequest request) {
RuntimeException e, HttpServletRequest request) {
log.warn("[RuntimeException] resource :{} ", e.getMessage());
String codeName = "INTERNAL_SERVER_ERROR";
ErrorLogEntity errorLog =
saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.CRITICAL,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.CRITICAL,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
}
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@@ -341,36 +372,36 @@ public class GlobalExceptionHandler {
String codeName = "INTERNAL_SERVER_ERROR";
ErrorLogEntity errorLog =
saveErrerLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.CRITICAL,
e.getStackTrace());
saveErrorLogData(
request,
ApiResponseCode.getCode(codeName),
HttpStatus.valueOf(codeName),
ErrorLogDto.LogErrorLevel.CRITICAL,
e.getStackTrace());
return ApiResponseDto.createException(
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
ApiResponseCode.getCode(codeName),
ApiResponseCode.getMessage(codeName),
HttpStatus.valueOf(codeName),
errorLog.getId());
}
/**
* 에러 로그 테이블 저장 로직
*
* @param request : request
* @param errorCode : 정의된 enum errorCode
* @param httpStatus : HttpStatus 값
* @param request : request
* @param errorCode : 정의된 enum errorCode
* @param httpStatus : HttpStatus 값
* @param logErrorLevel : WARNING, ERROR, CRITICAL
* @param stackTrace : 에러 내용
* @param stackTrace : 에러 내용
* @return : insert하고 결과로 받은 Entity
*/
private ErrorLogEntity saveErrerLogData(
HttpServletRequest request,
ApiResponseCode errorCode,
HttpStatus httpStatus,
ErrorLogDto.LogErrorLevel logErrorLevel,
StackTraceElement[] stackTrace) {
private ErrorLogEntity saveErrorLogData(
HttpServletRequest request,
ApiResponseCode errorCode,
HttpStatus httpStatus,
ErrorLogDto.LogErrorLevel logErrorLevel,
StackTraceElement[] stackTrace) {
Long userid = null;
@@ -384,35 +415,35 @@ public class GlobalExceptionHandler {
* 만든 CustomUserDetails 타입인가? 체크
*/
if (request.getUserPrincipal() instanceof UsernamePasswordAuthenticationToken auth
&& auth.getPrincipal() instanceof CustomUserDetails customUserDetails) {
&& auth.getPrincipal() instanceof CustomUserDetails customUserDetails) {
// audit 에는 long 타입 user_id가 들어가지만 토큰 sub은 uuid여서 user_id 가져오기
userid = customUserDetails.getMember().getId();
}
String stackTraceStr =
Arrays.stream(stackTrace)
.map(StackTraceElement::toString)
.collect(Collectors.joining("\n"))
.substring(0, Math.min(stackTrace.length, 255));
Arrays.stream(stackTrace)
.map(StackTraceElement::toString)
.collect(Collectors.joining("\n"))
.substring(0, Math.min(stackTrace.length, 255));
ErrorLogEntity errorLogEntity =
new ErrorLogEntity(
request.getRequestURI(),
ApiLogFunction.getEventType(request),
logErrorLevel,
String.valueOf(httpStatus.value()),
errorCode.getText(),
stackTraceStr,
userid,
ZonedDateTime.now());
new ErrorLogEntity(
request.getRequestURI(),
ApiLogFunction.getEventType(request),
logErrorLevel,
String.valueOf(httpStatus.value()),
errorCode.getText(),
stackTraceStr,
userid,
ZonedDateTime.now());
return errorLogRepository.save(errorLogEntity);
}
@ExceptionHandler(CustomApiException.class)
public ResponseEntity<ApiResponseDto<String>> handleCustomApiException(
CustomApiException e, HttpServletRequest request) {
CustomApiException e, HttpServletRequest request) {
log.warn("[CustomApiException] resource : {}", e.getMessage());
String codeName = e.getCodeName();
@@ -422,11 +453,11 @@ public class GlobalExceptionHandler {
ApiResponseCode apiCode = ApiResponseCode.getCode(codeName);
ErrorLogEntity errorLog =
saveErrerLogData(
request, apiCode, status, ErrorLogDto.LogErrorLevel.WARNING, e.getStackTrace());
saveErrorLogData(
request, apiCode, status, ErrorLogDto.LogErrorLevel.WARNING, e.getStackTrace());
ApiResponseDto<String> body =
ApiResponseDto.createException(apiCode, message, status, errorLog.getId());
ApiResponseDto.createException(apiCode, message, status, errorLog.getId());
return new ResponseEntity<>(body, status);
}

View File

@@ -86,7 +86,7 @@ public class AuthController {
.build();
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
return ApiResponseDto.createOK(new TokenResponse(accessToken));
return ApiResponseDto.ok(new TokenResponse(accessToken));
}
@PostMapping("/refresh")

View File

@@ -1,6 +1,7 @@
package com.kamco.cd.kamcoback.members.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@@ -10,7 +11,10 @@ import lombok.ToString;
@ToString(exclude = "password")
public class SignInRequest {
@Schema(description = "사번", example = "11111")
private String username;
@Schema(description = "비밀번호", example = "kamco1234!")
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;
}