Merge branch 'develop' into feature/event

This commit is contained in:
Hayoung Song
2025-10-27 13:43:15 +09:00
committed by GitHub
167 changed files with 10545 additions and 134 deletions
@@ -68,11 +68,14 @@ public enum ErrorCode {
DIST_004("DIST_004", "배포 상태를 찾을 수 없습니다"),
// 참여 에러 (PART_XXX)
PART_001("PART_001", "이미 참여한 이벤트입니다"),
PART_002("PART_002", "이벤트 참여 기간이 아닙니다"),
PART_003("PART_003", "참여자를 찾을 수 없습니다"),
PART_004("PART_004", "당첨자 추첨에 실패했습니다"),
PART_005("PART_005", "이벤트가 종료되었습니다"),
DUPLICATE_PARTICIPATION("PART_001", "이미 참여한 이벤트입니다"),
EVENT_NOT_ACTIVE("PART_002", "이벤트 참여 기간이 아닙니다"),
PARTICIPANT_NOT_FOUND("PART_003", "참여자를 찾을 수 없습니다"),
DRAW_FAILED("PART_004", "당첨자 추첨에 실패했습니다"),
EVENT_ENDED("PART_005", "이벤트가 종료되었습니다"),
ALREADY_DRAWN("PART_006", "이미 당첨자 추첨이 완료되었습니다"),
INSUFFICIENT_PARTICIPANTS("PART_007", "참여자 수가 당첨자 수보다 적습니다"),
NO_WINNERS_YET("PART_008", "아직 당첨자 추첨이 진행되지 않았습니다"),
// 분석 에러 (ANALYTICS_XXX)
ANALYTICS_001("ANALYTICS_001", "분석 데이터를 찾을 수 없습니다"),
@@ -2,6 +2,8 @@ package com.kt.event.common.exception;
import com.kt.event.common.dto.ErrorResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.mapping.PropertyReferenceException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
@@ -161,6 +163,66 @@ public class GlobalExceptionHandler {
.body(errorResponse);
}
/**
* 데이터 무결성 제약 위반 예외 처리
*
* @param ex 데이터 무결성 예외
* @return 에러 응답
*/
@ExceptionHandler(DataIntegrityViolationException.class)
public ResponseEntity<ErrorResponse> handleDataIntegrityViolationException(DataIntegrityViolationException ex) {
log.warn("Data integrity violation: {}", ex.getMessage());
String message = "데이터 중복 또는 무결성 제약 위반이 발생했습니다";
String details = ex.getMessage();
// 중복 키 에러인 경우 메시지 개선
if (ex.getMessage() != null) {
if (ex.getMessage().contains("uk_event_phone") || ex.getMessage().contains("phone_number")) {
message = "이미 참여하신 이벤트입니다";
details = "동일한 전화번호로 이미 참여 기록이 있습니다";
} else if (ex.getMessage().contains("participant_id")) {
message = "참여 처리 중 오류가 발생했습니다";
details = "잠시 후 다시 시도해주세요";
}
}
ErrorResponse errorResponse = ErrorResponse.of(
ErrorCode.DUPLICATE_PARTICIPATION.getCode(),
message,
details
);
return ResponseEntity
.status(HttpStatus.CONFLICT)
.body(errorResponse);
}
/**
* 잘못된 정렬 필드 예외 처리
*
* @param ex 속성 참조 예외
* @return 에러 응답
*/
@ExceptionHandler(PropertyReferenceException.class)
public ResponseEntity<ErrorResponse> handlePropertyReferenceException(PropertyReferenceException ex) {
log.warn("Invalid sort property: {}", ex.getMessage());
String message = "잘못된 정렬 필드입니다";
String details = String.format("'%s' 필드는 존재하지 않습니다. 사용 가능한 필드: id, participantId, eventId, name, phoneNumber, email, storeVisited, bonusEntries, agreeMarketing, agreePrivacy, isWinner, winnerRank, wonAt, createdAt, updatedAt",
ex.getPropertyName());
ErrorResponse errorResponse = ErrorResponse.of(
ErrorCode.COMMON_003.getCode(),
message,
details
);
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(errorResponse);
}
/**
* 일반 예외 처리
*