본문 바로가기

트러블슈팅

CustomException 처리 중 DB 저장 오류로 인한 500 에러 해결

문제 상황

 

잘못된 QR 코드로 출입 요청 시, INVALID_QR_CODE 예외가 발생해야 하지만 500 Internal Server Error 발생 !

 

 

기존 QR 출입 인증 처리 실패 플로우

 

1. 클라이언트가 QR 코드로 출입 요청

 

2. processQrAccess()에서 validateQr() 호출 - 요청받은 QR 코드 검증 수행

try{
	identifier = qrService.validateQr(request.getQrCode());
}

 

3. QR 유효성 검사 → 실패 시 CustomException(INVALID_QR_CODE) 발생

public String validateQr(String qrCode){
    try{
            String storedIdentifier = redisTemplate.opsForValue().get(qrCode);
            if(storedIdentifier == null){
                log.warn("QR 코드가 유효하지 않습니다: {}", qrCode);
                throw new CustomException(ErrorCode.INVALID_QR_CODE);
            }
            redisTemplate.delete(qrCode);
            return storedIdentifier;
        } catch (Exception e) {
            log.error("Redis 작업에 실패했습니다. QR code: {}, error: {}", qrCode, e.getMessage(), e);
            throw new CustomException(ErrorCode.REDIS_OPERATION_FAILED);
        }
}

 

4. 실패 로그 저장 - saveFailLog 호출

catch (CustomException e){
    logService.saveFailLog(AuthMethod.QR, null, e.getErrorCode());
    throw e;
}

 

5. 클라이언트에 예외 메시지 반환

400 Bad Request

ErrorResponse {"code": 400, "error": "INVALID_QR_CODE", "message": "유효하지 않은 QR 코드입니다."}

 

 

문제 원인
catch (CustomException e){
    logService.saveFailLog(AuthMethod.QR, null, e.getErrorCode());
    throw e;
}

 

FailLog에는 안면 인식과 QR 출입의 실패로그가 모두 저장됨

QR 출입에서는 similarity 필드가 필요하지 않아 null로 처리했던 것이 문제 !

 

saveFailLog 호출 시 similarity 필드가 null로 처리되어 저장

→ try 문에서 validateQr을 통해 INVALID_QR_CODE 에러를 catch하여 saveFailLog 메서드를 실행했지만,

DB 저장 시 500 에러가 발생하며 최종적으로 500 에러로 이어짐

 

 

문제 해결

 

saveFailLog 호출 시 similarity를 명시적으로 0.0f로 전달하여 DB 저장 시의 에러를 방지함

try{
	identifier = qrService.validateQr(request.getQrCode());
} catch (CustomException e){
    logService.saveFailLog(AuthMethod.QR, 0.0f, e.getErrorCode());
    throw e;
}

 

최종적으로 잘못된 QR 코드로 출입 요청 시,

saveFailLog에서 500 서버 에러가 발생하지 않고

qrService의 validateQr에서 발생한 INVALID_QR_CODE 에러가 그대로 전달되어 GlobalExceptionHandler를 통해 클라이언트에게 400 에러로 올바르게 반환됨 !

 

 

 

DB 저장 시 입력값 주의 !!!!!!