Skip to content

Conversation

@coli-geonwoo
Copy link
Collaborator

@coli-geonwoo coli-geonwoo commented Oct 14, 2025

🚩 연관 이슈

close #99

로깅 및 모니터링 시스템 도입 이전에 빠르게 에러를 확인할 수 있는 디스코드 연동을 진행합니다.

🔂 변경 내역

Summary by CodeRabbit

  • 신기능
    • 전역 예외 처리 도입: 애플리케이션 오류 시 표준화된 에러 응답(code/status/message) 반환
    • 오류 알림 기능 추가: 예외 발생 시 알림 채널(운영: Discord, 로컬/테스트: 콘솔)로 메시지 전송
  • 테스트
    • 오류 알림 동작 검증 테스트 추가(비활성화)
  • 스타일
    • 불필요한 공백 제거 등 코드 포맷 정리
  • 기타
    • 프로필별 알림 설정 구성 및 테스트 설정 파일 정리
    • 에러 코드 추가 및 일부 메시지 수정

@coli-geonwoo coli-geonwoo self-assigned this Oct 14, 2025
@coli-geonwoo coli-geonwoo linked an issue Oct 14, 2025 that may be closed by this pull request
@coderabbitai
Copy link

coderabbitai bot commented Oct 14, 2025

Walkthrough

전역 예외 처리에 오류 알림 연동을 추가하고, 도메인에 알림 포트/구현(Discord/Console)과 설정을 도입했다. Discord용 속성/의존성을 추가하고, 오류 메시지 포맷터와 에러 코드 항목을 확장했다. 테스트 환경 설정을 정리하고, 관련 테스트를 추가했다.

Changes

Cohort / File(s) Change Summary
Exception handling + notifier wiring (API apps)
gss-api-app/src/main/java/.../GlobalExceptionHandler.java, gss-mcp-app/src/main/java/com/devoops/exception/GlobalExceptionHandler.java, gss-mcp-app/src/main/java/com/devoops/exception/ErrorResponse.java
글로벌 예외 처리기에 ErrorNotifier 주입 및 호출 추가/신규 도입, ErrorResponse 레코드 추가, GssException/일반 Exception 처리 시 알림 전송 및 표준 응답 생성
Notifier domain introduction
gss-domain/src/main/java/com/devoops/config/NotifierConfig.java, gss-domain/src/main/java/com/devoops/domain/notifier/ErrorNotifier.java, gss-domain/src/main/java/com/devoops/domain/notifier/DiscordNotifier.java, gss-domain/src/main/java/com/devoops/domain/notifier/ConsoleNotifier.java, gss-domain/src/main/java/com/devoops/domain/notifier/DiscordProperties.java, gss-common/src/main/java/com/devoops/exception/notifier/NotifyPort.java, gss-domain/build.gradle
NotifyPort 인터페이스 및 구현(Discord/Console) 추가, 프로필별 빈 구성 추가(dev/prod=Discord, test/local=Console), DiscordProperties 바인딩/검증, JDA 의존성 및 컴파일 옵션 추가
Error message utilities + codes
gss-common/src/main/java/com/devoops/exception/message/ErrorMessageResolver.java, gss-common/src/main/java/com/devoops/exception/errorcode/ErrorCode.java
오류 메시지 문자열 생성 유틸 추가(스택 트레이스 일부 포함), DISCORD_PROPERTIES_EMPTY/DISCORD_JDA_EXCEPTION 코드 추가, AI_CHARGE_NOT_FOUND 메시지 오탈자 수정
Tests and test configs
gss-api-app/src/test/java/com/devoops/notifier/adapter/ErrorNotifierTest.java, gss-api-app/src/test/resources/application-test.yml, src/test/resources/application-ci.yml, src/test/resources/application.yml
ErrorNotifier 테스트 추가(@disabled), 테스트용 설정에서 jwt/discord 등 루트 구성 복원, CI/기본 테스트용 YAML 제거로 설정 단순화
Minor formatting
gss-api-app/src/main/java/.../JwtProperties.java
불필요한 공백 라인 제거(동작 변경 없음)

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Client
  participant App as API App
  participant GEH as GlobalExceptionHandler
  participant EN as ErrorNotifier
  participant NP as NotifyPort
  participant DN as DiscordNotifier/ConsoleNotifier
  participant DC as Discord (JDA)

  Client->>App: 요청
  App-->>GEH: 예외 발생
  GEH->>EN: notify(exception)
  EN->>EN: ErrorMessageResolver.resolve()
  EN->>NP: sendMessage(message)
  NP->>DN: dispatch
  alt dev/prod
    DN->>DC: send message (async)
    DC-->>DN: ack
  else test/local
    DN-->>DN: console 출력
  end
  GEH-->>Client: ResponseEntity(ErrorResponse)

  rect rgb(245,245,255)
  note right of DN: 초기화 시\nJDA ready 대기
  end

  %% Error path
  DN--x GEH: GssException(DISCORD_JDA_EXCEPTION)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

Possibly related PRs

없음

Suggested labels

feat

Pre-merge checks and finishing touches

❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning PR에는 Discord 알림 기능 구현과 직접 무관한 JwtProperties 포매팅 변경 및 application.yml·application-ci.yml에서 테스트 및 CI 환경 설정을 제거한 변경이 포함되어 있어 범위를 벗어난 것으로 보입니다. 테스트 및 CI 설정 관련 변경은 별도의 PR로 분리하거나 불필요하다면 원복하여 기능 구현과 관련된 변경만 남겨주세요.
Description Check ⚠️ Warning PR 설명은 연관 이슈 섹션을 제대로 포함하고 있지만 변경 내역 섹션에 구현된 주요 변경 내용이 전혀 기재되지 않아 템플릿 요건을 충족하지 못합니다. 변경 내역 섹션에 구현된 클래스 추가, 예외 처리 로직 변경, 설정 파일 수정 등 주요 변경 사항을 간략한 항목으로 추가하여 템플릿을 완성해주세요.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed PR 제목 "[FEAT] 500에러 디스코드 알림 기능 구현"은 500 에러 발생 시 디스코드 알림 기능 추가라는 핵심 변경 사항을 간결하고 명확하게 표현하여 변경 내용과 완전히 일치합니다.
Linked Issues Check ✅ Passed 이 PR은 이슈 #99의 요구사항인 500 에러 발생 시 디스코드 알림 전송을 위한 NotifyPort 인터페이스, DiscordNotifier 구현체, ErrorNotifier 클래스, GlobalExceptionHandler 수정 및 설정 파일 추가를 통해 기능을 충실히 구현하고 있습니다.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/#99-discord-error

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

Test Results

0 tests   0 ✅  0s ⏱️
0 suites  0 💤
0 files    0 ❌

Results for commit bf4deb3.

@github-actions
Copy link

📝 Test Coverage Report

Overall Project NaN% NaN% 🍏

There is no coverage information present for the Files changed

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (9)
gss-domain/src/main/java/com/devoops/domain/notifier/DiscordProperties.java (1)

15-20: 검증 로직 개선 권장

현재 구현은 tokenchannelId를 개별적으로 검증하지만, 어떤 속성이 누락되었는지 구분하지 못합니다. 사용자 경험 개선을 위해 구체적인 에러 메시지 제공을 권장합니다.

다음과 같이 개선할 수 있습니다:

-    public DiscordProperties(String token, String channelId) {
-        validate(token);
-        validate(channelId);
+    public DiscordProperties(String token, String channelId) {
+        validate(token, "token");
+        validate(channelId, "channelId");
         this.token = token;
         this.channelId = channelId;
     }

-    private void validate(String element) {
+    private void validate(String element, String propertyName) {
         if (element == null || element.isBlank()) {
-            throw new GssException(ErrorCode.DISCORD_PROPERTIES_EMPTY);
+            throw new GssException(ErrorCode.DISCORD_PROPERTIES_EMPTY, 
+                    "디스코드 속성이 비어있습니다: " + propertyName);
         }
     }
gss-api-app/src/test/java/com/devoops/notifier/adapter/ErrorNotifierTest.java (1)

10-11: 비활성화된 테스트에 대한 설명 필요

테스트가 @Disabled로 비활성화되어 있지만 이유가 명시되지 않았습니다. 통합 테스트로 인한 외부 의존성 때문이라면, 목(mock)을 사용한 단위 테스트로 전환하거나 비활성화 이유를 주석으로 명시하는 것을 권장합니다.

다음과 같이 개선할 수 있습니다:

-@Disabled
+@Disabled("Discord 외부 연동이 필요한 통합 테스트 - 로컬 환경에서만 수동 실행")
 class ErrorNotifierTest extends BaseControllerTest {

또는 목을 사용한 단위 테스트를 생성하시겠습니까?

gss-domain/src/main/java/com/devoops/domain/notifier/ConsoleNotifier.java (1)

8-11: 로거 사용 권장

테스트/로컬 환경용이지만, System.out.println 대신 로거를 사용하는 것이 로그 레벨 제어, 포맷 일관성, 테스트 검증 측면에서 더 좋습니다.

다음과 같이 개선할 수 있습니다:

+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
 public class ConsoleNotifier implements NotifyPort {
 
     @Override
     public void sendMessage(String message) {
-        System.out.println("[메시지 발송] : " + message);
+        log.info("[메시지 발송] : {}", message);
     }
 }
gss-domain/src/main/java/com/devoops/domain/notifier/DiscordNotifier.java (2)

22-29: JDA 초기화 예외 범위가 협소합니다 (LoginException 등). 포괄 처리 권장.

토큰 오류 등에서 build()/awaitReady()가 다른 예외를 던질 수 있습니다. 공통 처리로 감싸 주세요.

     private JDA initializeJda(String token) {
         try {
             return JDABuilder.createDefault(token).build().awaitReady();
         } catch (InterruptedException e) {
             Thread.currentThread().interrupt();
             throw new GssException(ErrorCode.DISCORD_JDA_EXCEPTION);
+        } catch (Exception e) {
+            log.error("Failed to initialize JDA", e);
+            throw new GssException(ErrorCode.DISCORD_JDA_EXCEPTION);
         }
     }

해당 JDA 버전에서 실제로 어떤 예외가 발생하는지 확인 부탁드립니다. 필요 시 구체 타입(LoginException 등)으로 분기 처리해도 좋습니다.


17-20: 부팅 블로킹/게이트웨이 과부하 최소화 제안

단순 알림 전송 목적이면 게이트웨이 연결 없이 Webhook 사용 또는 createLight(token)(필요 인텐트 최소화)로 경량화하는 편이 안전하고 빠릅니다.

예:

// 경량 모드(인텐트 비활성화)
return JDABuilder.createLight(token).build().awaitReady();
// 또는 Webhook (게이트웨이 미접속, 토큰 권한 노출 최소화)

운영에서의 토큰 권한/인텐트 최소화도 점검해 주세요.

gss-common/src/main/java/com/devoops/exception/message/ErrorMessageResolver.java (1)

13-22: 디스코드 2,000자 제한 보호 로직 추가 제안

현재 길이 제한이 없어 드물게 2,000자 초과 시 전송 실패합니다. 동적으로 잘라내세요.

     public static String resolve(Throwable throwable) {
         String errorMessage = throwable.toString();
         String stackTrace = getStackTraceAsString(throwable);
 
-        return NOTIFICATION_PREFIX
-                + errorMessage
-                + STACK_TRACE_AFFIX
-                + stackTrace
-                + STACK_TRACE_AFFIX;
+        String content = NOTIFICATION_PREFIX
+                + errorMessage
+                + STACK_TRACE_AFFIX
+                + stackTrace
+                + STACK_TRACE_AFFIX;
+        // Discord message hard limit: 2000 chars
+        if (content.length() <= 2000) {
+            return content;
+        }
+        int overhead = (NOTIFICATION_PREFIX + errorMessage + STACK_TRACE_AFFIX + STACK_TRACE_AFFIX).length() + 3; // for "..."
+        int maxStackLen = Math.max(0, 2000 - overhead);
+        String truncated = stackTrace.length() > maxStackLen
+                ? stackTrace.substring(0, maxStackLen) + "..."
+                : stackTrace;
+        return NOTIFICATION_PREFIX + errorMessage + STACK_TRACE_AFFIX + truncated + STACK_TRACE_AFFIX;
     }

원하면 상수로 2000을 추출하고 테스트도 추가해 드릴게요.

gss-domain/src/main/java/com/devoops/config/NotifierConfig.java (2)

18-18: @configuration(proxyBeanMethods = false)로 불필요한 CGLIB 프록시 방지 제안

빈 간 상호 참조가 없다면 성능·시작속도 측면에서 이점이 있습니다.

-    @Configuration
+    @Configuration(proxyBeanMethods = false)
...
-    @Configuration
+    @Configuration(proxyBeanMethods = false)

Also applies to: 32-32


31-33: 프로필 미설정(default) 환경에서 NotifyPort 미바인딩 가능성 확인

항상 dev/prod/test/local 중 하나가 활성인지 확인해주세요. 아니라면 default에도 콘솔 노티파이어를 노출하는 편이 안전합니다.

-    @Profile({"test", "local"})
+    @Profile({"test", "local", "default"})

또는 @ConditionalOnProperty("discord.enabled")로 토글하는 접근도 고려해 보세요. 운영 편의에 유리합니다.

gss-mcp-app/src/main/java/com/devoops/exception/GlobalExceptionHandler.java (1)

19-24: 알림 실패가 예외 처리 흐름을 깨지 않도록 보호하세요

errorNotifier.notify(...) 실패가 응답 생성까지 방해하지 않게 try/catch로 감싸는 것이 안전합니다.

     public ResponseEntity<ErrorResponse> handleGssException(GssException exception) {
         log.error("Custom GssException occurred: {}", exception.getMessage(), exception);
-        errorNotifier.notify(exception);
+        try {
+            errorNotifier.notify(exception);
+        } catch (Exception notifyEx) {
+            log.warn("Failed to notify error", notifyEx);
+        }
         return toResponse(exception.getErrorCode());
     }
@@
     public ResponseEntity<ErrorResponse> handleException(Exception exception) {
         log.error("Unhandled exception occurred", exception);
-        errorNotifier.notify(exception);
+        try {
+            errorNotifier.notify(exception);
+        } catch (Exception notifyEx) {
+            log.warn("Failed to notify error", notifyEx);
+        }
         return toResponse(ErrorCode.INTERNAL_SERVER_ERROR);
     }

Also applies to: 26-31

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 56cd305 and bf4deb3.

📒 Files selected for processing (17)
  • gss-api-app/src/main/java/com/devoops/exception/GlobalExceptionHandler.java (4 hunks)
  • gss-api-app/src/main/java/com/devoops/service/auth/jwt/JwtProperties.java (0 hunks)
  • gss-api-app/src/test/java/com/devoops/notifier/adapter/ErrorNotifierTest.java (1 hunks)
  • gss-api-app/src/test/resources/application-test.yml (2 hunks)
  • gss-common/src/main/java/com/devoops/exception/errorcode/ErrorCode.java (1 hunks)
  • gss-common/src/main/java/com/devoops/exception/message/ErrorMessageResolver.java (1 hunks)
  • gss-common/src/main/java/com/devoops/exception/notifier/NotifyPort.java (1 hunks)
  • gss-domain/build.gradle (2 hunks)
  • gss-domain/src/main/java/com/devoops/config/NotifierConfig.java (1 hunks)
  • gss-domain/src/main/java/com/devoops/domain/notifier/ConsoleNotifier.java (1 hunks)
  • gss-domain/src/main/java/com/devoops/domain/notifier/DiscordNotifier.java (1 hunks)
  • gss-domain/src/main/java/com/devoops/domain/notifier/DiscordProperties.java (1 hunks)
  • gss-domain/src/main/java/com/devoops/domain/notifier/ErrorNotifier.java (1 hunks)
  • gss-mcp-app/src/main/java/com/devoops/exception/ErrorResponse.java (1 hunks)
  • gss-mcp-app/src/main/java/com/devoops/exception/GlobalExceptionHandler.java (1 hunks)
  • src/test/resources/application-ci.yml (0 hunks)
  • src/test/resources/application.yml (0 hunks)
💤 Files with no reviewable changes (3)
  • src/test/resources/application.yml
  • src/test/resources/application-ci.yml
  • gss-api-app/src/main/java/com/devoops/service/auth/jwt/JwtProperties.java
🧰 Additional context used
🧬 Code graph analysis (6)
gss-domain/src/main/java/com/devoops/config/NotifierConfig.java (1)
gss-domain/src/main/java/com/devoops/domain/notifier/ConsoleNotifier.java (1)
  • ConsoleNotifier (6-12)
gss-api-app/src/test/java/com/devoops/notifier/adapter/ErrorNotifierTest.java (1)
gss-client/gss-github-client/src/main/java/com/devoops/exception/GithubNotFoundException.java (1)
  • GithubNotFoundException (3-7)
gss-domain/src/main/java/com/devoops/domain/notifier/ErrorNotifier.java (1)
gss-common/src/main/java/com/devoops/exception/message/ErrorMessageResolver.java (1)
  • ErrorMessageResolver (6-30)
gss-domain/src/main/java/com/devoops/domain/notifier/DiscordNotifier.java (2)
gss-api-app/src/main/java/com/devoops/exception/GlobalExceptionHandler.java (1)
  • Slf4j (20-96)
gss-mcp-app/src/main/java/com/devoops/exception/GlobalExceptionHandler.java (1)
  • Slf4j (12-38)
gss-mcp-app/src/main/java/com/devoops/exception/GlobalExceptionHandler.java (2)
gss-api-app/src/main/java/com/devoops/exception/GlobalExceptionHandler.java (1)
  • Slf4j (20-96)
gss-domain/src/main/java/com/devoops/domain/notifier/DiscordNotifier.java (1)
  • Slf4j (11-36)
gss-domain/src/main/java/com/devoops/domain/notifier/DiscordProperties.java (1)
gss-api-app/src/main/java/com/devoops/service/auth/jwt/JwtProperties.java (1)
  • Getter (11-37)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-and-push
🔇 Additional comments (8)
gss-api-app/src/test/resources/application-test.yml (1)

22-41: 테스트 프로퍼티 복원 👍
테스트 프로필에서도 JWT·CORS·Discord 프로퍼티를 루트로 두어 바인딩이 끊기지 않게 정리한 부분 확인했습니다. 의도대로 통합 테스트가 안정적으로 동작할 것 같습니다.

gss-domain/build.gradle (1)

40-42: LGTM!

-parameters 컴파일러 옵션 추가는 Spring의 리플렉션 기반 기능(파라미터 이름 기반 autowiring 등)에 필요한 올바른 설정입니다.

gss-common/src/main/java/com/devoops/exception/notifier/NotifyPort.java (1)

3-6: LGTM!

알림 기능을 위한 깔끔한 포트 인터페이스 정의입니다. 헥사고날 아키텍처 패턴을 따르고 있어 구현체 교체가 용이합니다.

gss-common/src/main/java/com/devoops/exception/errorcode/ErrorCode.java (2)

44-44: LGTM!

오타 수정이 적절합니다 ("찾을 없습니다" → "찾을 수 없습니다").


45-46: LGTM!

Discord 관련 에러 코드가 명확하게 정의되었습니다. 두 가지 케이스(속성 누락, JDA 초기화 실패)를 모두 커버하고 있습니다.

gss-api-app/src/main/java/com/devoops/exception/GlobalExceptionHandler.java (2)

25-25: LGTM!

ErrorNotifier 의존성 추가가 적절합니다. @RequiredArgsConstructor를 통한 생성자 주입을 사용하고 있습니다.


84-89: LGTM!

일반 Exception 처리에 알림 기능이 추가되어 예상치 못한 500 에러를 모두 캐치할 수 있습니다.

gss-mcp-app/src/main/java/com/devoops/exception/ErrorResponse.java (1)

6-18: LGTM!

ErrorCode로부터 ErrorResponse를 생성하는 레코드 구현이 깔끔합니다. HttpStatus 변환 로직도 적절합니다.

Comment on lines 72 to 77
@ExceptionHandler(GssException.class)
public ResponseEntity<ErrorResponse> handleGssException(GssException exception) {
log.error("Custom GssException occurred: {}", exception.getMessage(), exception);
errorNotifier.notify(exception);
return toResponse(exception.getErrorCode());
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

500 에러에 대한 알림 범위 검증 필요

현재 GssException에 대해서만 알림이 발송되지만, PR 목표는 "500 에러에 대한 디스코드 알림"입니다. GssException 중에서도 4xx 상태 코드를 반환하는 경우가 있는지 확인이 필요합니다.

다음 스크립트로 GssException이 사용되는 모든 위치와 해당 ErrorCode의 상태 코드를 확인하세요:


🏁 Script executed:

#!/bin/bash
# GssException 사용처 검색
echo "=== GssException 사용 위치 ==="
rg -n "throw new GssException" -A 1 -B 1

echo -e "\n=== ErrorCode 4xx vs 5xx 분포 ==="
rg -n "^\s+\w+\([45]\d{2}," gss-common/src/main/java/com/devoops/exception/errorcode/ErrorCode.java

Length of output: 10618


5xx 에러만 디스코드 알림 전송하도록 필터링 추가 필요

GlobalExceptionHandler.java(handleGssException 메서드 72-77)에서 exception.getErrorCode().getStatus()가 500 이상일 때만 errorNotifier.notify 호출하도록 분기 처리하세요.

🤖 Prompt for AI Agents
In gss-api-app/src/main/java/com/devoops/exception/GlobalExceptionHandler.java
around lines 72 to 77, the handler currently always calls errorNotifier.notify
for GssException; change it to only call errorNotifier.notify when
exception.getErrorCode().getStatus() is 500 or greater. Keep the existing log
and response behavior, but wrap the errorNotifier.notify call in a conditional
that checks exception.getErrorCode().getStatus() >= 500 so only server (5xx)
errors trigger Discord notifications.

Comment on lines +23 to +24
//Discord
implementation 'net.dv8tion:JDA:5.0.0-beta.24'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

베타 버전 사용에 대한 검증 필요

JDA 5.0.0-beta.24는 베타 버전으로 프로덕션 환경에서 안정성 이슈가 발생할 수 있습니다. 최신 안정 버전(GA) 사용을 권장합니다.

다음 스크립트를 실행하여 최신 안정 버전을 확인하세요:


🏁 Script executed:

#!/bin/bash
# JDA 최신 버전 및 보안 권고사항 확인
curl -s https://repo1.maven.org/maven2/net/dv8tion/JDA/maven-metadata.xml | grep -A 1 "<release>"

# GitHub에서 최신 릴리즈 확인
gh api repos/discord-jda/JDA/releases/latest --jq '.tag_name'

Length of output: 62


JDA 베타 버전 대신 최신 안정 GA(6.0.0) 버전 사용
gss-domain/build.gradle:23에서 5.0.0-beta.246.0.0으로 변경하세요.

🤖 Prompt for AI Agents
In gss-domain/build.gradle around lines 23 to 24, the dependency uses the JDA
beta version '5.0.0-beta.24'; update this to the stable GA release by changing
the implementation line to use 'net.dv8tion:JDA:6.0.0'. Ensure you update any
transitive or repository constraints if needed and run a Gradle refresh to
verify compatibility.

Comment on lines +31 to +35
@Override
public void sendMessage(String message) {
TextChannel channel = jda.getTextChannelById(properties.getChannelId());
channel.sendMessage(message).queue();
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

채널 null 시 NPE 발생 가능. null 체크 및 전송 실패 콜백 추가하세요.

getTextChannelById가 null일 수 있어 NPE 위험이 있습니다. 실패 콜백도 등록해 전송 오류를 로깅하세요.

-    public void sendMessage(String message) {
-        TextChannel channel = jda.getTextChannelById(properties.getChannelId());
-        channel.sendMessage(message).queue();
-    }
+    public void sendMessage(String message) {
+        TextChannel channel = jda.getTextChannelById(properties.getChannelId());
+        if (channel == null) {
+            log.error("Discord TextChannel not found. channelId={}", properties.getChannelId());
+            return;
+        }
+        channel.sendMessage(message).queue(
+            success -> { /* no-op */ },
+            throwable -> log.error("Failed to send Discord message", throwable)
+        );
+    }
📝 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.

Suggested change
@Override
public void sendMessage(String message) {
TextChannel channel = jda.getTextChannelById(properties.getChannelId());
channel.sendMessage(message).queue();
}
@Override
public void sendMessage(String message) {
TextChannel channel = jda.getTextChannelById(properties.getChannelId());
if (channel == null) {
log.error("Discord TextChannel not found. channelId={}", properties.getChannelId());
return;
}
channel.sendMessage(message).queue(
success -> { /* no-op */ },
throwable -> log.error("Failed to send Discord message", throwable)
);
}
🤖 Prompt for AI Agents
In gss-domain/src/main/java/com/devoops/domain/notifier/DiscordNotifier.java
around lines 31 to 35, the code calls jda.getTextChannelById(...) and
immediately uses the result, which can be null and cause an NPE; update the
method to check for a null TextChannel and log an error (and return) if not
found, and when calling channel.sendMessage(message) add a failure callback
(e.g., queue(success -> {}, failure -> log the exception and context)) so any
send errors are logged with details.

TextChannel channel = jda.getTextChannelById(properties.getChannelId());
channel.sendMessage(message).queue();
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

애플리케이션 종료 시 JDA 종료 누락(스레드/리소스 릭 위험). @PreDestroy 추가 권장.

종료 훅에서 JDA를 내려 안전하게 스레드를 정리하세요.

 }
+    @jakarta.annotation.PreDestroy
+    void shutdown() {
+        try {
+            jda.shutdown();
+        } catch (Exception e) {
+            log.warn("Error while shutting down JDA", e);
+        }
+    }

추가 import:

import jakarta.annotation.PreDestroy;

Spring Boot 3/Spring 6는 jakarta.* 네임스페이스를 사용합니다. Based on learnings

🤖 Prompt for AI Agents
In gss-domain/src/main/java/com/devoops/domain/notifier/DiscordNotifier.java
around line 36, the class currently does not shut down the JDA client on
application exit, risking thread/resource leaks; add a method annotated with
jakarta.annotation.PreDestroy that calls jda.shutdownNow() (or the appropriate
JDA shutdown method) to cleanly stop JDA, and add the import
jakarta.annotation.PreDestroy; ensure the method checks for null and handles
exceptions so shutdown is attempted safely during application teardown.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] 500에러 디스코드 알림 기능 구현

2 participants