✨ [기능추가] 동적인 스케쥴러를 구현을 위해 배치와 설정을 테스크스케쥴러로 등록 - #108
Conversation
[기능추가] 동적인 스케쥴러를 구현을 위해 배치와 설정을 테스크스케쥴러로 등록
[기능추가] 배치, 엘라스틱 서치 테스크 스케쥴러 추가 구현완료
[기능추가] 테스크 스케쥴러에 배치, 핫토핏, 엘라스틱 서치 스케쥴링 완료
|
Caution Review failedThe pull request is closed. Walkthrough스프링 부트 애플리케이션에 뉴스 배치 처리 및 사용자별 카카오 뉴스 메시지 스케줄링 기능이 대규모로 추가 및 개선되었습니다. 배치 스케줄러, 사용자별 스케줄러, 스케줄러 초기화, 커스텀 예외 및 에러코드, Swagger 문서화, 서비스 및 저장소 메서드 확장 등 다양한 영역에서 신규 기능 구현과 리팩토링이 이루어졌습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant SchedulerInitializer
participant SettingService
participant TaskSchedulerService
participant KakaoSchedulerService
participant KakaoMessageService
SchedulerInitializer->>SettingService: getAllSettings()
SettingService-->>SchedulerInitializer: List<Setting>
loop 각 Setting
SchedulerInitializer->>TaskSchedulerService: scheduleUser(setting)
TaskSchedulerService->>KakaoSchedulerService: getCron(setting)
TaskSchedulerService->>KakaoMessageService: sendKakaoMessage(refreshToken, userId)
KakaoMessageService-->>TaskSchedulerService: (성공/실패)
end
sequenceDiagram
participant BatchSchedulerService
participant DBBatchService
participant ESBatchService
participant HotTopicService
participant TaskSchedulerService
BatchSchedulerService->>DBBatchService: runDbBatch()
DBBatchService-->>BatchSchedulerService: 완료
BatchSchedulerService->>ESBatchService: runEsBulkIndexing()
ESBatchService-->>BatchSchedulerService: 완료
BatchSchedulerService->>HotTopicService: collectAndSaveHotTopics()
HotTopicService-->>BatchSchedulerService: 완료
BatchSchedulerService->>TaskSchedulerService: registerUserSchedules()
TaskSchedulerService-->>BatchSchedulerService: 완료
Suggested labels
Suggested reviewers
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (3)
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 11
🧹 Nitpick comments (12)
SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/TaskSchedulerConfig.java (2)
8-21: TaskScheduler 설정 검토 및 개선 제안TaskScheduler 구성이 전반적으로 잘 설계되었습니다. 다음과 같은 개선사항을 제안합니다:
풀 사이즈를 설정 파일에서 관리할 수 있도록 외부화하는 것을 고려해보세요:
+@Value("${scheduler.pool.size:10}") +private int poolSize; + @Bean("customTaskScheduler") public TaskScheduler taskScheduler() { ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); - scheduler.setPoolSize(10); // 동시 작업 수 + scheduler.setPoolSize(poolSize); // 동시 작업 수이렇게 하면 환경별로 다른 풀 사이즈를 설정할 수 있습니다.
10-10: 주석 개선 제안주석의 문법을 개선하여 더 명확하게 작성할 수 있습니다.
- //동적인 스케쥴러를 사용자로부터 받아오기 위해 taskScheduler로 스케쥴을 동적으로 받아옴. + // 동적 스케줄러를 구현하기 위한 TaskScheduler 빈 설정SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoMessageService.java (2)
171-180: 에러 처리 개선 승인DB와 Elasticsearch 간의 데이터 불일치를 우아하게 처리하는 로직으로 개선되었습니다. 예외 발생 대신 경고 로그를 남기고 처리를 계속하는 것은 시스템 안정성 향상에 도움이 됩니다.
주석 처리된 기존 코드를 정리하는 것을 고려해보세요:
-// News newsitem = newsRepository.findById(Long.parseLong(newsDoc.getId())) -// .orElseThrow(() -> new RuntimeException("뉴스가 존재하지 않습니다: " + newsDoc.getId())); - - /* DB와 ES 동기화 되어있지 않을 시, 잡는 예외 */ + // DB와 ES 동기화 되어있지 않을 시 처리 News newsitem = newsRepository.findById(Long.parseLong(newsDoc.getId())) .orElse(null);
174-174: 주석 문법 개선 제안주석의 문법을 더 명확하게 작성할 수 있습니다.
- /* DB와 ES 동기화 되어있지 않을 시, 잡는 예외 */ + // DB와 ES 동기화 불일치 시 예외 처리SpringBoot/src/main/java/Baemin/News_Deliver/Global/JWT/JwtAuthenticationFilter.java (1)
148-155: 주석 처리된 코드 제거 권장버전 관리 시스템을 통해 이전 코드를 확인할 수 있으므로, 주석 처리된 원본 코드는 제거하는 것이 좋습니다.
- - //원본 코드 -// return path.startsWith("/api/auth/") -// || path.startsWith("/login/oauth2/") -// || path.startsWith("/oauth2/") -// || path.equals("/") -// || path.startsWith("/css/") -// || path.startsWith("/js/") -// || path.startsWith("/images/");SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/BatchSchedulerService.java (1)
108-164: 주석 처리된 원본 코드 제거 권장대량의 주석 처리된 코드가 가독성을 해치고 있습니다. Git 히스토리를 통해 확인 가능합니다.
주석 처리된 원본 코드를 모두 제거하시기 바랍니다.
SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/TaskSchedulerService.java (2)
15-16: 불필요한 import 제거 필요
@Component와@Service어노테이션을 모두 import했지만, 클래스에서는@Service만 사용하고 있습니다.-import org.springframework.stereotype.Component; import org.springframework.stereotype.Service;
41-92: 주석처리된 핵심 기능 구현 완료 필요스케줄러의 핵심 기능인
scheduleUser메서드가 주석처리되어 있습니다. 동적 스케줄러 구현이 PR의 목적인 만큼, 이 기능의 구현 완료가 필요합니다.주석처리된 코드에서 확인된 잠재적 문제점:
- 87라인에서
cron변수가 정의되지 않음- 예외 처리 로직이 포함되어 있어 안정성 고려됨
이 메서드를 활성화하고 완성하는 데 도움이 필요하시면 알려주세요.
SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/controller/KakaoController.java (1)
64-85: 재시도 로직 검토 필요1차 실패 후 2차 재시도 로직이 구현되어 있지만, 재시도 간격이나 백오프 전략이 없습니다. 연속적인 재시도가 외부 API에 부하를 줄 수 있습니다.
재시도 간격 추가를 고려해보세요:
// 재시도 전 잠시 대기 Thread.sleep(1000); // 1초 대기.github/workflows/dev-test.yml (1)
67-67: trailing spaces 제거 필요YAMLlint에서 지적한 trailing spaces 문제를 해결해야 합니다.
- echo "⏳ Dev 테스트 환경 준비 중..." + echo "⏳ Dev 테스트 환경 준비 중..."모든 trailing spaces를 제거하세요.
Also applies to: 73-73, 84-84, 89-89, 100-100, 106-106, 112-112, 120-120, 123-123, 128-128, 139-139, 143-143, 146-146, 149-149, 155-155, 158-158, 191-191
docker-compose.yml (1)
160-160: 파일 끝에 개행 문자 추가 필요YAMLlint에서 지적한 대로 파일 끝에 개행 문자를 추가해야 합니다.
networks: backend: driver: bridge +.github/workflows/deploy-prod.yml (1)
38-38: YAML 형식 오류 수정 필요YAMLlint에서 지적한 trailing spaces와 파일 끝 개행 문자 누락을 해결해야 합니다.
- git pull origin ${{ github.ref_name }} + git pull origin ${{ github.ref_name }}모든 trailing spaces를 제거하고 파일 끝에 개행 문자를 추가하세요.
Also applies to: 44-44, 48-48, 51-51, 54-54, 63-63, 67-67, 70-70, 73-73, 76-76, 79-79, 82-82, 91-91, 97-97, 100-100, 103-103, 107-107, 111-111, 119-119, 128-128, 137-137, 146-146, 155-155, 161-161, 164-164, 170-170, 177-177, 179-179, 182-182, 185-185, 189-189, 193-193, 195-195, 206-206, 212-212, 239-239
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
SpringBoot/.DS_Storeis excluded by!**/.DS_Store
📒 Files selected for processing (16)
.github/workflows/deploy-prod.yml(2 hunks).github/workflows/dev-test.yml(4 hunks)SpringBoot/Dockerfile(1 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/controller/KakaoController.java(3 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoMessageService.java(1 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoSchedulerService.java(3 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Mypage/service/SettingService.java(2 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Global/JWT/JwtAuthenticationFilter.java(1 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/BatchSchedulerService.java(1 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/SchedulerInitializer.java(1 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/TaskSchedulerConfig.java(1 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/TaskSchedulerService.java(1 hunks)SpringBoot/src/main/resources/application-test.properties(2 hunks)SpringBoot/src/main/resources/application.properties(1 hunks)docker-compose.yml(6 hunks)nginx/nginx.conf(0 hunks)
💤 Files with no reviewable changes (1)
- nginx/nginx.conf
🧰 Additional context used
🪛 YAMLlint (1.37.1)
.github/workflows/dev-test.yml
[error] 67-67: trailing spaces
(trailing-spaces)
[error] 73-73: trailing spaces
(trailing-spaces)
[error] 84-84: trailing spaces
(trailing-spaces)
[error] 89-89: trailing spaces
(trailing-spaces)
[error] 100-100: trailing spaces
(trailing-spaces)
[error] 106-106: trailing spaces
(trailing-spaces)
[error] 112-112: trailing spaces
(trailing-spaces)
[error] 120-120: trailing spaces
(trailing-spaces)
[error] 123-123: trailing spaces
(trailing-spaces)
[error] 128-128: trailing spaces
(trailing-spaces)
[error] 139-139: trailing spaces
(trailing-spaces)
[error] 143-143: trailing spaces
(trailing-spaces)
[error] 146-146: trailing spaces
(trailing-spaces)
[error] 149-149: trailing spaces
(trailing-spaces)
[error] 155-155: trailing spaces
(trailing-spaces)
[error] 158-158: trailing spaces
(trailing-spaces)
[error] 191-191: trailing spaces
(trailing-spaces)
.github/workflows/deploy-prod.yml
[error] 38-38: trailing spaces
(trailing-spaces)
[error] 44-44: trailing spaces
(trailing-spaces)
[error] 48-48: trailing spaces
(trailing-spaces)
[error] 51-51: trailing spaces
(trailing-spaces)
[error] 54-54: trailing spaces
(trailing-spaces)
[error] 63-63: trailing spaces
(trailing-spaces)
[error] 67-67: trailing spaces
(trailing-spaces)
[error] 70-70: trailing spaces
(trailing-spaces)
[error] 73-73: trailing spaces
(trailing-spaces)
[error] 76-76: trailing spaces
(trailing-spaces)
[error] 79-79: trailing spaces
(trailing-spaces)
[error] 82-82: trailing spaces
(trailing-spaces)
[error] 91-91: trailing spaces
(trailing-spaces)
[error] 97-97: trailing spaces
(trailing-spaces)
[error] 100-100: trailing spaces
(trailing-spaces)
[error] 103-103: trailing spaces
(trailing-spaces)
[error] 107-107: trailing spaces
(trailing-spaces)
[error] 111-111: trailing spaces
(trailing-spaces)
[error] 119-119: trailing spaces
(trailing-spaces)
[error] 128-128: trailing spaces
(trailing-spaces)
[error] 137-137: trailing spaces
(trailing-spaces)
[error] 146-146: trailing spaces
(trailing-spaces)
[error] 155-155: trailing spaces
(trailing-spaces)
[error] 161-161: trailing spaces
(trailing-spaces)
[error] 164-164: trailing spaces
(trailing-spaces)
[error] 170-170: trailing spaces
(trailing-spaces)
[error] 177-177: trailing spaces
(trailing-spaces)
[error] 179-179: trailing spaces
(trailing-spaces)
[error] 182-182: trailing spaces
(trailing-spaces)
[error] 185-185: trailing spaces
(trailing-spaces)
[error] 189-189: trailing spaces
(trailing-spaces)
[error] 193-193: trailing spaces
(trailing-spaces)
[error] 195-195: trailing spaces
(trailing-spaces)
[error] 206-206: trailing spaces
(trailing-spaces)
[error] 212-212: trailing spaces
(trailing-spaces)
[error] 239-239: no new line character at the end of file
(new-line-at-end-of-file)
docker-compose.yml
[error] 160-160: no new line character at the end of file
(new-line-at-end-of-file)
🔇 Additional comments (23)
SpringBoot/src/main/resources/application-test.properties (1)
4-4: 코드 가독성 향상을 위한 주석 추가 승인설정 파일의 가독성과 구조화를 위해 주석을 추가한 것은 좋은 개선사항입니다. 각 설정 섹션이 명확하게 구분되어 유지보수가 용이해졌습니다.
Also applies to: 7-7, 13-13, 19-19, 27-27, 53-53, 56-56, 62-62
SpringBoot/Dockerfile (1)
23-25: 타임존 설정 구현 승인Asia/Seoul 타임존 설정이 올바르게 구현되었습니다. 다음과 같은 좋은 관행을 따르고 있습니다:
- tzdata 패키지 설치 후 정리를 통한 이미지 크기 최적화
- 여러 타임존 설정 방법 병행 사용으로 호환성 확보
- 환경 변수 설정으로 애플리케이션 레벨 타임존 일관성 보장
SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/BatchSchedulerService.java (1)
25-25: 순환 의존성 없음 확인
SchedulerInitializer.java에서BatchSchedulerService에 대한 참조는 모두 주석 처리되어 있어 현재 순환 의존성이 발생하지 않습니다.
불필요한 주석 코드는 제거하여 가독성을 개선하는 것을 권장드립니다.SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/TaskSchedulerService.java (2)
17-17: @transactional 사용 검토 필요
@Transactional어노테이션이 import되었지만 클래스나 메서드에서 사용되지 않습니다. 스케줄러 서비스에서 데이터베이스 트랜잭션 처리가 필요한지 검토하세요.
39-39: 스레드 안전성 잘 고려됨
ConcurrentHashMap을 사용하여 멀티스레드 환경에서의 안전성을 적절히 고려했습니다.SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/controller/KakaoController.java (4)
12-14: Swagger 문서화 개선 완료OpenAPI 3.0 어노테이션을 적절히 추가하여 API 문서화가 크게 개선되었습니다.
23-30: 클래스 레벨 문서화 우수Javadoc과
@Tag어노테이션을 통해 클래스의 목적이 명확히 문서화되었습니다.
43-50: 상세한 API 문서화 제공
@Operation어노테이션으로 API의 동작과 응답 코드를 상세히 문서화했습니다. 개발자 경험 향상에 도움이 됩니다.
60-60: 매개변수화된 로깅으로 개선
log.info("유저 RefreshToken 확인: {}", allUsersRefreshToken)등과 같이 매개변수화된 로깅을 사용하여 성능과 가독성이 향상되었습니다.Also applies to: 68-68, 88-88
.github/workflows/dev-test.yml (5)
12-12: 테스트 시간 제한 설정 우수12분 타임아웃 설정으로 무한 대기 상황을 방지했습니다.
53-60: Gradle 캐시 최적화 우수Gradle 패키지 캐시를 추가하여 빌드 시간을 크게 단축할 수 있습니다.
64-92: 병렬 서비스 체크 로직 우수서비스 준비 상태를 병렬로 확인하여 전체 대기 시간을 단축했습니다. 백그라운드 작업과
wait명령어를 활용한 구현이 효율적입니다.
94-161: 동적 설정 파일 생성 우수테스트 환경에 필요한 모든 설정을 동적으로 생성하여 환경 독립성을 확보했습니다. 특히 Asia/Seoul 타임존 설정이 일관성 있게 적용되었습니다.
171-179: 실패 시에만 테스트 리포트 업로드
if: failure()조건을 사용하여 실패 시에만 아티팩트를 업로드하도록 최적화했습니다.docker-compose.yml (3)
9-9: 타임존 일관성 강화 우수모든 서비스에
TZ=Asia/Seoul환경변수와 타임존 관련 볼륨 마운트를 추가하여 시스템 전체의 시간 동기화를 보장했습니다.Also applies to: 31-32, 49-49, 64-65, 73-73, 77-78, 87-87, 93-94, 103-103, 109-110, 118-118, 131-132
29-29: 포트 매핑 변경 확인nginx 제거에 따라 Spring Boot 서비스를 직접 80 포트로 노출하도록 변경했습니다. 이는 아키텍처 단순화에 도움이 됩니다.
54-54: MySQL 타임존 설정 추가MySQL 서버의 기본 타임존을 +09:00으로 설정하여 데이터베이스 레벨에서도 타임존 일관성을 확보했습니다.
.github/workflows/deploy-prod.yml (6)
34-37: 동적 브랜치 처리 개선
${{ github.ref_name }}을 사용하여 동적으로 브랜치를 처리하도록 개선했습니다. 이는 다양한 브랜치에서의 배포를 지원합니다.
45-48: 컨테이너 정리 과정 개선
--remove-orphans --timeout 30옵션과docker system prune -f를 추가하여 더 철저한 컨테이너 정리를 수행합니다.
58-121: 고급 디버깅 기능 추가배포 후 문제 진단을 위한 포괄적인 디버깅 정보 수집 로직을 추가했습니다. Docker 상태, 로그, 네트워크, 시스템 리소스 등을 체계적으로 확인합니다.
123-172: 컨테이너별 개별 테스트 우수각 컨테이너(MySQL, Redis, Elasticsearch, Spring Boot)에 대해 개별적으로 상태를 확인하는 로직을 추가했습니다. 문제 발생 시 원인을 빠르게 파악할 수 있습니다.
174-221: 유연한 헬스체크 로직여러 엔드포인트를 순차적으로 테스트하고, 하나라도 성공하면 배포 성공으로 간주하는 유연한 접근 방식을 적용했습니다.
223-239: 배포 요약 정보 개선GitHub Actions 요약에 동적 브랜치 정보와 유용한 링크들을 포함하여 배포 결과를 명확히 제공합니다.
| spring.security.oauth2.client.registration.kakao.client-secret=${KAKAO_CLIENT_SECRET} | ||
| spring.security.oauth2.client.registration.kakao.client-authentication-method=client_secret_post | ||
| spring.security.oauth2.client.registration.kakao.redirect-uri=http://43.201.27.98/login/oauth2/code/kakao | ||
| spring.security.oauth2.client.registration.kakao.redirect-uri=http://localhost:8080/login/oauth2/code/kakao |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
OAuth2 리다이렉트 URI 변경 사항 검토 필요
리다이렉트 URI가 고정 IP 주소에서 localhost로 변경되었습니다. 이는 로컬 개발 환경에서는 정상 작동하지만, 프로덕션 환경에서는 문제가 될 수 있습니다.
다음 스크립트를 실행하여 다른 환경별 설정 파일이 있는지 확인하겠습니다:
🏁 Script executed:
#!/bin/bash
# 다른 환경별 application.properties 파일들을 찾아서 OAuth2 설정 확인
fd -e properties application | xargs grep -l "oauth2.client.registration.kakao.redirect-uri" || trueLength of output: 203
다음으로 application-test.properties에서 설정된 리다이렉트 URI를 확인합니다:
🏁 Script executed:
#!/bin/bash
grep -n "spring.security.oauth2.client.registration.kakao.redirect-uri" SpringBoot/src/main/resources/application-test.properties || trueLength of output: 239
OAuth2 리다이렉트 URI 환경별 설정 검토 및 수정 필요
현재 두 개의 프로퍼티 파일에서 서로 다른 localhost URI가 설정되어 있습니다. 프로덕션 환경으로 배포 시 실제 도메인·포트로 변경되지 않으면 OAuth2 인증 흐름이 실패할 수 있습니다.
• SpringBoot/src/main/resources/application.properties (default)
– spring.security.oauth2.client.registration.kakao.redirect-uri=http://localhost:8080/login/oauth2/code/kakao
• SpringBoot/src/main/resources/application-test.properties (test)
– spring.security.oauth2.client.registration.kakao.redirect-uri=http://localhost/api/login/oauth2/code/kakao
제안
- application-{profile}.properties 혹은 환경 변수로 URI를 외부화하여 개발·테스트·프로덕션마다 별도로 관리
- 프로덕션 배포 전에 실제 리다이렉트 URI(예: https://your-domain.com/login/oauth2/code/kakao)로 설정 확인
- CI/CD 파이프라인이나 Spring Cloud Config 등을 활용해 환경별 프로퍼티 분리
🤖 Prompt for AI Agents
In SpringBoot/src/main/resources/application.properties at line 45, the OAuth2
redirect URI is hardcoded to a localhost address, which differs from the test
properties and will cause failures in production. Refactor the configuration to
externalize the redirect URI using environment-specific property files like
application-{profile}.properties or environment variables. Ensure that for
production, the redirect URI is set to the actual domain and port, and integrate
this setup into your CI/CD pipeline or configuration management to manage
environment-specific values properly.
| return path.startsWith("/login/oauth2/") | ||
| || path.startsWith("/oauth2/") | ||
| || path.equals("/") | ||
| || path.startsWith("/css/") | ||
| || path.startsWith("/js/") | ||
| || path.startsWith("/images/"); |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
인증이 필요한 엔드포인트가 제외되었는지 확인 필요
/api/auth/ 및 / 경로가 JWT 필터 제외 목록에서 제거되었습니다. 이는 보안 강화일 수 있지만, 일반적으로 인증 관련 API는 JWT 없이도 접근 가능해야 합니다.
다음 스크립트를 실행하여 /api/auth/ 엔드포인트가 인증 없이도 접근 가능한지 확인하세요:
🏁 Script executed:
#!/bin/bash
# /api/auth/ 경로를 사용하는 컨트롤러 메서드 확인
ast-grep --pattern 'class $_ {
$$$
@$_Mapping($$$"/api/auth/$$$"$$$)
$_($$$) {
$$$
}
$$$
}'Length of output: 107
다음 스크립트를 실행하여 /api/auth/ 및 루트(/) 경로에 매핑된 컨트롤러 메서드가 있는지 확인하세요.
🏁 Script executed:
#!/bin/bash
# /api/auth/ 경로를 사용하는 컨트롤러 메서드 확인
rg -n '@.*Mapping.*"/api/auth' .
# 루트("/") 경로를 사용하는 컨트롤러 메서드 확인
rg -n '@.*Mapping.*"/"' .Length of output: 184
다음 스크립트를 실행하여 /api/auth 컨트롤러 매핑과 정적 리소스(특히 루트 경로) 구성을 확인해주세요:
🏁 Script executed:
#!/bin/bash
echo "=== Index.html 위치 확인 ==="
find SpringBoot/src/main/resources -type f -name "index.html" || echo "index.html 없음"
echo "=== 정적 리소스 디렉토리 목록 확인 (resources/static) ==="
find SpringBoot/src/main/resources/static -maxdepth 1 -type f -print 2>/dev/null || echo "resources/static 디렉토리 없음"
echo "=== AuthController 클래스 및 앞뒤 10줄 ==="
rg -n 'class AuthController' -A10 SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Auth/Controller/AuthController.java
echo "=== AuthController 내 매핑 어노테이션 전체 ==="
rg -n '@.*Mapping' SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Auth/Controller/AuthController.javaLength of output: 1241
JWT 필터 예외 경로에 /api/auth 미포함으로 인한 토큰 처리 실패 우려
AuthController가 /api/auth에 매핑되어 있어 다음 엔드포인트들이 현재 JWT 필터의 보호 대상에 포함되어 있습니다.
- POST /api/auth/refresh
- POST /api/auth/logout
- GET /api/auth/me
- GET /api/auth/status
이로 인해 토큰 갱신·로그아웃·사용자 조회 기능이 정상 동작하지 않을 수 있으므로, JWT 필터의 shouldNotFilter 예외 목록에 적절히 추가하거나 경로별 예외 처리 로직을 세분화해야 합니다.
• 대상 파일:
SpringBoot/src/main/java/Baemin/News_Deliver/Global/JWT/JwtAuthenticationFilter.java (라인 142–146)
• 제안 diff:
@@ -142,6 +142,7 @@
return path.startsWith("/login/oauth2/")
|| path.startsWith("/oauth2/")
+ || path.startsWith("/api/auth/refresh")
|| path.startsWith("/css/")
|| path.startsWith("/js/")
|| path.startsWith("/images/");필요하다면 /api/auth/logout 등 추가 경로도 함께 검토·추가 바랍니다.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| return path.startsWith("/login/oauth2/") | |
| || path.startsWith("/oauth2/") | |
| || path.equals("/") | |
| || path.startsWith("/css/") | |
| || path.startsWith("/js/") | |
| || path.startsWith("/images/"); | |
| return path.startsWith("/login/oauth2/") | |
| || path.startsWith("/oauth2/") | |
| || path.startsWith("/api/auth/refresh") | |
| || path.startsWith("/css/") | |
| || path.startsWith("/js/") | |
| || path.startsWith("/images/"); |
🤖 Prompt for AI Agents
In
SpringBoot/src/main/java/Baemin/News_Deliver/Global/JWT/JwtAuthenticationFilter.java
around lines 142 to 146, the JWT filter's shouldNotFilter method is missing the
/api/auth path in its exception list, causing token processing failures for
endpoints like /api/auth/refresh, /api/auth/logout, /api/auth/me, and
/api/auth/status. To fix this, add path.startsWith("/api/auth/") to the existing
conditions to exclude these endpoints from JWT filtering, and consider adding
more specific paths like /api/auth/logout if needed for finer control.
| public Setting getById(Long settingId) { | ||
| return settingRepository.findById(settingId).get(); | ||
| } |
There was a problem hiding this comment.
Optional.get() 직접 호출은 위험합니다
Optional.get()을 체크 없이 호출하면 값이 없을 때 NoSuchElementException이 발생합니다. 다른 메서드들처럼 적절한 예외 처리가 필요합니다.
public Setting getById(Long settingId) {
- return settingRepository.findById(settingId).get();
+ return settingRepository.findById(settingId)
+ .orElseThrow(() -> new SettingException(ErrorCode.SETTING_NOT_FOUND));
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| public Setting getById(Long settingId) { | |
| return settingRepository.findById(settingId).get(); | |
| } | |
| public Setting getById(Long settingId) { | |
| return settingRepository.findById(settingId) | |
| .orElseThrow(() -> new SettingException(ErrorCode.SETTING_NOT_FOUND)); | |
| } |
🤖 Prompt for AI Agents
In
SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Mypage/service/SettingService.java
around lines 270 to 272, the method calls Optional.get() directly without
checking if a value is present, which can cause NoSuchElementException if the
setting is not found. Modify the method to handle the absence of the value
safely by using Optional.orElseThrow() with a custom exception or a suitable
alternative to provide proper exception handling instead of calling get()
directly.
| public List<Setting> getAllSettings() { | ||
| return settingRepository.findAll(); | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
활성 설정만 반환하도록 필터링 추가 고려
getAllSettings()는 삭제된 설정을 포함한 모든 설정을 반환합니다. 스케줄러에서 사용한다면 활성 설정만 필요할 것으로 보입니다.
public List<Setting> getAllSettings() {
- return settingRepository.findAll();
+ return settingRepository.findAll().stream()
+ .filter(setting -> !setting.getIsDeleted())
+ .filter(setting -> setting.getEndDate() == null || setting.getEndDate().isAfter(LocalDateTime.now()))
+ .toList();
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| public List<Setting> getAllSettings() { | |
| return settingRepository.findAll(); | |
| } | |
| public List<Setting> getAllSettings() { | |
| return settingRepository.findAll().stream() | |
| .filter(setting -> !setting.getIsDeleted()) | |
| .filter(setting -> setting.getEndDate() == null | |
| || setting.getEndDate().isAfter(LocalDateTime.now())) | |
| .toList(); | |
| } |
🤖 Prompt for AI Agents
In
SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Mypage/service/SettingService.java
around lines 266 to 268, the getAllSettings() method currently returns all
settings including deleted ones. Modify this method to filter and return only
active settings, for example by adding a condition to query only settings where
the active flag is true or deleted flag is false, depending on your entity
design, so that only active settings are returned.
|
|
||
| @PostConstruct | ||
| public void scheduleNewsBatch() { | ||
| String cron = "0 17 17 * * *"; |
There was a problem hiding this comment.
테스트용 크론 표현식 수정 필요
현재 크론 표현식이 매일 17:17에 실행되도록 설정되어 있습니다. 주석에는 자정 실행이라고 되어 있는데 불일치합니다.
- String cron = "0 17 17 * * *";
+ String cron = "0 0 0 * * *"; // 매일 자정📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| String cron = "0 17 17 * * *"; | |
| String cron = "0 0 0 * * *"; // 매일 자정 |
🤖 Prompt for AI Agents
In
SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/BatchSchedulerService.java
at line 36, the cron expression is set to run daily at 17:17, which conflicts
with the comment stating it should run at midnight. Update the cron expression
to "0 0 0 * * *" to schedule the task to run at midnight daily, ensuring the
code matches the comment.
| private boolean isSettingTableAvailable() { | ||
| try { | ||
| settingRepository.count(); | ||
| return true; | ||
| } catch (Exception e) { | ||
| log.warn("[SchedulerInit] 테이블 확인 중 오류 발생: {}", e.getMessage()); | ||
| return false; | ||
| } | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
너무 광범위한 예외 처리
모든 예외를 잡아서 false를 반환하면 실제 설정 문제를 숨길 수 있습니다. 데이터베이스 연결 문제와 테이블 부재를 구분해야 합니다.
private boolean isSettingTableAvailable() {
try {
settingRepository.count();
return true;
+ } catch (org.springframework.dao.InvalidDataAccessResourceUsageException e) {
+ // 테이블이 없는 경우
+ log.warn("[SchedulerInit] setting 테이블이 존재하지 않습니다: {}", e.getMessage());
+ return false;
} catch (Exception e) {
- log.warn("[SchedulerInit] 테이블 확인 중 오류 발생: {}", e.getMessage());
+ log.error("[SchedulerInit] 데이터베이스 접근 중 예상치 못한 오류 발생: {}", e.getMessage(), e);
return false;
}
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| private boolean isSettingTableAvailable() { | |
| try { | |
| settingRepository.count(); | |
| return true; | |
| } catch (Exception e) { | |
| log.warn("[SchedulerInit] 테이블 확인 중 오류 발생: {}", e.getMessage()); | |
| return false; | |
| } | |
| } | |
| private boolean isSettingTableAvailable() { | |
| try { | |
| settingRepository.count(); | |
| return true; | |
| } catch (org.springframework.dao.InvalidDataAccessResourceUsageException e) { | |
| // 테이블이 없는 경우 | |
| log.warn("[SchedulerInit] setting 테이블이 존재하지 않습니다: {}", e.getMessage()); | |
| return false; | |
| } catch (Exception e) { | |
| log.error("[SchedulerInit] 데이터베이스 접근 중 예상치 못한 오류 발생: {}", e.getMessage(), e); | |
| return false; | |
| } | |
| } |
🤖 Prompt for AI Agents
In
SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/SchedulerInitializer.java
between lines 68 and 76, the method isSettingTableAvailable() currently catches
all exceptions broadly, which can mask real configuration issues. Refine the
exception handling to specifically catch exceptions related to the table not
existing (e.g., DataAccessException or a more specific subclass) and return
false only in those cases. For other exceptions like database connection errors,
allow them to propagate or handle them separately to avoid hiding critical
problems.
[기능 추가] 사용자 셋팅값을 받아 메세지 전송 완료
left a comment
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/SchedulerInitializer.java (1)
66-74: 예외 처리 개선 필요과거 리뷰 코멘트에서 지적된 바와 같이, 모든 예외를 포괄적으로 처리하면 실제 설정 문제를 숨길 수 있습니다. 테이블 부재와 데이터베이스 연결 문제를 구분하여 처리해야 합니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoSchedulerService.java(3 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Mypage/Repository/SettingRepository.java(2 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/BatchSchedulerService.java(1 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/SchedulerInitializer.java(1 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/TaskSchedulerService.java(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/BatchSchedulerService.java
- SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoSchedulerService.java
🧰 Additional context used
🧬 Code Graph Analysis (1)
SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/TaskSchedulerService.java (4)
SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/SchedulerInitializer.java (1)
Component(16-76)SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoSchedulerService.java (1)
Service(21-71)SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Mypage/service/SettingService.java (1)
Service(43-273)SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoMessageService.java (1)
Service(31-210)
🔇 Additional comments (9)
SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Mypage/Repository/SettingRepository.java (2)
12-12: Optional import 추가 승인새로운 메서드의 반환 타입을 위해 필요한 import가 적절히 추가되었습니다.
35-40: JPQL 쿼리 구현이 우수함LEFT JOIN FETCH를 사용하여 days 컬렉션을 즉시 로딩하는 것은 스케줄러에서 LazyInitializationException을 방지하는 좋은 접근입니다. 쿼리 문법과 Optional 반환 타입 사용이 적절합니다.
SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/SchedulerInitializer.java (1)
54-62: 사용자별 스케줄링 로직 승인각 Setting에 대해 개별적으로 예외 처리를 하면서 스케줄링하는 로직이 적절합니다. 하나의 설정 실패가 전체 스케줄링을 중단시키지 않도록 잘 구현되었습니다.
SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/TaskSchedulerService.java (6)
31-32: 커스텀 TaskScheduler 사용 승인@qualifier를 사용하여 커스텀 TaskScheduler를 명시적으로 주입하는 것이 적절합니다. 이를 통해 스케줄링 설정을 세밀하게 제어할 수 있습니다.
47-49: 즉시 로딩으로 LazyInitializationException 방지
findByIdWithDays()메서드를 사용하여 days 컬렉션을 즉시 로딩하는 것은 스케줄된 작업에서 발생할 수 있는 LazyInitializationException을 효과적으로 방지합니다.
54-57: 중복 스케줄 방지 로직 우수기존 스케줄이 있는 경우 취소 후 새로 등록하는 로직이 적절합니다. 이를 통해 중복 스케줄링을 방지할 수 있습니다.
40-40: 스레드 안전한 작업 추적 구현 우수ConcurrentHashMap을 사용하여 스케줄된 작업을 추적하고 관리하는 것이 멀티스레드 환경에서 안전합니다.
Also applies to: 94-95
101-109: 스케줄 취소 메커니즘 적절사용자와 설정 ID를 기반으로 특정 스케줄을 취소하는 메커니즘이 잘 구현되었습니다. 적절한 로깅도 포함되어 있습니다.
73-90: 스케줄된 작업의 예외 처리 우수스케줄된 작업 내에서 설정 존재 여부를 확인하고 예외를 적절히 처리하는 로직이 견고합니다. 하나의 작업 실패가 전체 스케줄러에 영향을 주지 않도록 잘 구현되었습니다.
| .map(Auth::getKakaoRefreshToken)) | ||
| .orElseThrow(() -> new IllegalArgumentException("유저 또는 리프레시 토큰이 존재하지 않습니다.")); | ||
|
|
||
| log.info("[Scheduler] 토큰 확인 완료 - {}", refreshAccessToken); |
There was a problem hiding this comment.
보안 위험: 리프레시 토큰 로깅
리프레시 토큰을 전체 로그에 출력하는 것은 보안 위험을 초래할 수 있습니다. 토큰의 일부만 마스킹하여 로깅하는 것을 권장합니다.
- log.info("[Scheduler] 토큰 확인 완료 - {}", refreshAccessToken);
+ log.info("[Scheduler] 토큰 확인 완료 - {}****", refreshAccessToken.substring(0, Math.min(8, refreshAccessToken.length())));📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| log.info("[Scheduler] 토큰 확인 완료 - {}", refreshAccessToken); | |
| log.info("[Scheduler] 토큰 확인 완료 - {}****", | |
| refreshAccessToken.substring(0, Math.min(8, refreshAccessToken.length()))); |
🤖 Prompt for AI Agents
In
SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/TaskSchedulerService.java
at line 66, the code logs the full refresh token which poses a security risk.
Modify the log statement to mask most of the token, for example by showing only
the first few and last few characters with the middle replaced by asterisks or
dots, to prevent exposing sensitive information while still allowing some
traceability.
[기능추가] 문서화 주석 달아둠
left a comment
There was a problem hiding this comment.
Actionable comments posted: 2
🔭 Outside diff range comments (1)
SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoMessageService.java (1)
172-173: 논리 오류: 히스토리 저장 성공 시 null 반환현재 로직은 히스토리가 성공적으로 저장되면 null을 반환하고 있습니다. 이는 의도와 반대인 것으로 보입니다:
- if (saveHistory(newsList, settings)) return null; + saveHistory(newsList, settings); return newsList;또는 저장 실패 시 예외를 발생시키는 방식을 고려해보세요.
♻️ Duplicate comments (1)
SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/TaskSchedulerService.java (1)
97-97: 보안 위험: 리프레시 토큰 전체 로깅리프레시 토큰을 전체 로그에 출력하는 것은 보안상 위험합니다. 토큰의 일부만 마스킹하여 로깅하는 것을 권장합니다.
- log.info("[Scheduler] 토큰 확인 완료 - {}", refreshAccessToken); + log.info("[Scheduler] 토큰 확인 완료 - {}...", refreshAccessToken.substring(0, Math.min(8, refreshAccessToken.length())));
🧹 Nitpick comments (1)
SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/TaskSchedulerService.java (1)
85-130: 스케줄 등록의 원자성 개선 권장기존 스케줄을 취소한 후 새 스케줄 등록 과정에서 예외가 발생하면 사용자의 스케줄이 완전히 사라질 수 있습니다. 더 안전한 방식을 고려해보세요:
- // 이미 등록된 경우 기존 스케줄 취소 - if (scheduledTasks.containsKey(taskKey)) { - cancelUser(userId, settingId); - } + // 기존 스케줄은 나중에 취소하도록 보관 + ScheduledFuture<?> existingTask = scheduledTasks.get(taskKey); // ... 새 스케줄 생성 로직 ... CronTrigger trigger = new CronTrigger(cron); ScheduledFuture<?> future = taskScheduler.schedule(task, trigger); - scheduledTasks.put(taskKey, future); + + // 새 스케줄 등록 성공 시에만 기존 스케줄 취소 + scheduledTasks.put(taskKey, future); + if (existingTask != null) { + existingTask.cancel(false); + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/controller/KakaoController.java(3 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/repository/HistoryRepository.java(1 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoMessageService.java(7 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoSchedulerService.java(2 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Mypage/Repository/SettingRepository.java(2 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Global/Exception/ErrorCode.java(2 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/BatchSchedulerService.java(1 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/SchedulerConfig.java(1 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/SchedulerInitializer.java(1 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/TaskSchedulerConfig.java(1 hunks)SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/TaskSchedulerService.java(1 hunks)
✅ Files skipped from review due to trivial changes (2)
- SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/repository/HistoryRepository.java
- SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/SchedulerConfig.java
🚧 Files skipped from review as they are similar to previous changes (6)
- SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Mypage/Repository/SettingRepository.java
- SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/TaskSchedulerConfig.java
- SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/BatchSchedulerService.java
- SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/SchedulerInitializer.java
- SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoSchedulerService.java
- SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/controller/KakaoController.java
🧰 Additional context used
🧬 Code Graph Analysis (1)
SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoMessageService.java (1)
SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/entity/History.java (1)
Entity(13-44)
🔇 Additional comments (5)
SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/TaskSchedulerService.java (1)
138-158: 스케줄 취소 및 키 생성 로직 적절함스케줄 취소와 키 생성 메서드가 잘 구현되어 있습니다. 사용자별, 설정별로 고유한 키를 생성하여 중복 스케줄을 방지하는 구조가 좋습니다.
SpringBoot/src/main/java/Baemin/News_Deliver/Global/Exception/ErrorCode.java (1)
42-64: 에러 코드 추가 적절함새로 추가된 카카오 및 스케줄러 관련 에러 코드들이 기존 규칙을 잘 따르고 있으며, 명확한 메시지와 적절한 HTTP 상태 코드를 가지고 있습니다.
SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoMessageService.java (3)
76-86: 예외 처리 개선 확인
RuntimeException대신KakaoException을 사용하여 일관된 예외 처리를 구현한 것이 좋습니다.
183-196: 템플릿 데이터 생성 메서드 추가 적절함뉴스 리스트를 카카오 템플릿용 데이터로 변환하는 헬퍼 메서드가 잘 구현되었습니다. 최대 5개 제한도 적절합니다.
219-224: DB/ES 동기화 문제 처리 개선ElasticSearch와 DB 간 동기화 문제를 우아하게 처리하도록 개선되었습니다. 예외를 발생시키는 대신 경고 로그를 남기고 계속 진행하는 방식이 적절합니다.
| if (newsList == null) return false; | ||
|
|
||
| //뉴스가 없을 때 반환할 값을 고민 해볼 것. | ||
| if (newsList == null) new KakaoException(ErrorCode.NO_NEWS_DATA);; |
There was a problem hiding this comment.
문법 오류: 예외가 throw되지 않음
예외 객체를 생성하지만 throw하지 않고 있으며, 세미콜론이 중복되어 있습니다:
- if (newsList == null) new KakaoException(ErrorCode.NO_NEWS_DATA);;
+ if (newsList == null) throw new KakaoException(ErrorCode.NO_NEWS_DATA);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (newsList == null) new KakaoException(ErrorCode.NO_NEWS_DATA);; | |
| if (newsList == null) throw new KakaoException(ErrorCode.NO_NEWS_DATA); |
🤖 Prompt for AI Agents
In
SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoMessageService.java
at line 102, the code creates a new KakaoException but does not throw it, and
there is an extra semicolon. Fix this by adding the 'throw' keyword before the
new KakaoException to properly throw the exception, and remove the redundant
semicolon.
| } catch (Exception e) { | ||
| log.error("[Scheduler] 유저 {} / setting {} 메시지 발송 중 예외 발생: {}", userId, settingId, e.getMessage(), e); | ||
| throw new KakaoException(ErrorCode.MESSAGE_SEND_FAILED); | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
예외 처리 개선 필요
일반적인 Exception을 잡는 것보다 구체적인 예외를 처리하는 것이 좋습니다. 또한 원본 예외를 보존해야 합니다:
- } catch (Exception e) {
- log.error("[Scheduler] 유저 {} / setting {} 메시지 발송 중 예외 발생: {}", userId, settingId, e.getMessage(), e);
- throw new KakaoException(ErrorCode.MESSAGE_SEND_FAILED);
+ } catch (KakaoException e) {
+ log.error("[Scheduler] 유저 {} / setting {} 메시지 발송 중 카카오 예외 발생: {}", userId, settingId, e.getMessage(), e);
+ throw e; // 원본 예외 재발생
+ } catch (Exception e) {
+ log.error("[Scheduler] 유저 {} / setting {} 메시지 발송 중 예외 발생: {}", userId, settingId, e.getMessage(), e);
+ throw new KakaoException(ErrorCode.MESSAGE_SEND_FAILED, e); // 원본 예외를 cause로 포함
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| } catch (Exception e) { | |
| log.error("[Scheduler] 유저 {} / setting {} 메시지 발송 중 예외 발생: {}", userId, settingId, e.getMessage(), e); | |
| throw new KakaoException(ErrorCode.MESSAGE_SEND_FAILED); | |
| } | |
| } catch (KakaoException e) { | |
| log.error("[Scheduler] 유저 {} / setting {} 메시지 발송 중 카카오 예외 발생: {}", userId, settingId, e.getMessage(), e); | |
| throw e; // 원본 예외 재발생 | |
| } catch (Exception e) { | |
| log.error("[Scheduler] 유저 {} / setting {} 메시지 발송 중 예외 발생: {}", userId, settingId, e.getMessage(), e); | |
| throw new KakaoException(ErrorCode.MESSAGE_SEND_FAILED, e); // 원본 예외를 cause로 포함 | |
| } |
🤖 Prompt for AI Agents
In
SpringBoot/src/main/java/Baemin/News_Deliver/Global/Scheduler/TaskSchedulerService.java
around lines 119 to 122, replace the generic Exception catch block with more
specific exceptions relevant to the message sending process. Also, when throwing
the KakaoException, pass the caught exception as the cause to preserve the
original exception details for better debugging and error tracing.
스케쥴러 배치, 엘라스틱서치, 핫토픽 스케쥴링 완료
Summary by CodeRabbit
신규 기능
개선 사항
버그 수정/정리
문서화