Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,6 @@ public class GlobalExceptionHandler {

private final NotifyClientAdapter<DiscordExceptionNotifyEventRequest> notifier;

private void notifyIfNeeded(Exception ex) {
try {
DiscordExceptionNotifyEventRequest request = DiscordExceptionNotifyEventRequest.of(
ex.getCause().toString(),
ex.getMessage()
);
notifier.send(request);
} catch (Exception notifyEx) {
log.error("[Discord Notify Error]", notifyEx);
}
}

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleMethodArgumentNotValidException(
MethodArgumentNotValidException ex) {
Expand Down Expand Up @@ -94,9 +82,9 @@ public ResponseEntity<ErrorResponse> handleAuthenticationException(Authenticatio
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
}

@ExceptionHandler(life.mosu.mosuserver.global.exception.AuthenticationException.class)
@ExceptionHandler(AuthenticationException.class)
public ResponseEntity<ErrorResponse> handleCustomAuthenticationException(
life.mosu.mosuserver.global.exception.AuthenticationException ex) {
AuthenticationException ex) {
Comment on lines +85 to +87

Choose a reason for hiding this comment

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

critical

This change introduces an ambiguity in exception handling. Both this method (handleCustomAuthenticationException) and handleAuthenticationException (line 72) now handle AuthenticationException.class.

Due to the import import org.springframework.security.core.AuthenticationException; on line 14, AuthenticationException.class resolves to org.springframework.security.core.AuthenticationException.class. This results in two handlers for the same exception, which will cause an IllegalStateException at runtime and prevent the application from starting.

To fix this, you should revert to using the fully qualified class name for your custom AuthenticationException to distinguish it from Spring's AuthenticationException.

Suggested change
@ExceptionHandler(AuthenticationException.class)
public ResponseEntity<ErrorResponse> handleCustomAuthenticationException(
life.mosu.mosuserver.global.exception.AuthenticationException ex) {
AuthenticationException ex) {
@ExceptionHandler(life.mosu.mosuserver.global.exception.AuthenticationException.class)
public ResponseEntity<ErrorResponse> handleCustomAuthenticationException(
life.mosu.mosuserver.global.exception.AuthenticationException ex) {

notifyIfNeeded(ex);

ErrorResponse response = ErrorResponse.builder()
Expand Down Expand Up @@ -160,4 +148,16 @@ public ResponseEntity<ErrorResponse> handleCustomRuntimeException(CustomRuntimeE

return ResponseEntity.status(ex.getStatus()).body(response);
}

private void notifyIfNeeded(Exception ex) {
try {
DiscordExceptionNotifyEventRequest request = DiscordExceptionNotifyEventRequest.of(
ex.getCause().toString(),
ex.getMessage()
);
Comment on lines +154 to +157

Choose a reason for hiding this comment

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

high

The call ex.getCause().toString() on line 155 will throw a NullPointerException if ex.getCause() returns null. Many exceptions are thrown without a cause, which would make this notification logic fail silently (the NPE would be caught and logged, but the original exception notification would not be sent).

To make the notification more robust, you should handle the case where the cause is null.

Suggested change
DiscordExceptionNotifyEventRequest request = DiscordExceptionNotifyEventRequest.of(
ex.getCause().toString(),
ex.getMessage()
);
DiscordExceptionNotifyEventRequest request = DiscordExceptionNotifyEventRequest.of(
ex.getCause() != null ? ex.getCause().toString() : "N/A",
ex.getMessage()
);

notifier.send(request);
} catch (Exception notifyEx) {
log.error("[Discord Notify Error]", notifyEx);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static DiscordExceptionNotifyEventRequest of(
}

public String getMessage() {
return " **알림 전송 실패**\n"
return "⚠️ **알림 전송**\n"
+ String.format("- ⚠️ exception Cause : `%s`\n", exceptionCause)
+ String.format("- 📨 exception Message: `%s`\n", exceptionMessage)
+ String.format("- 📋 meta: `%s`", meta == null ? "없음" : meta);
Comment on lines +25 to 28

Choose a reason for hiding this comment

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

medium

Using the + operator for string concatenation can be inefficient as it creates multiple intermediate String objects. For better performance and readability, you can use a single String.format() for the entire message template.

If you are using Java 15+, you could also consider using a text block with the .formatted() method for even better readability.

Suggested change
return "⚠️ **알림 전송**\n"
+ String.format("- ⚠️ exception Cause : `%s`\n", exceptionCause)
+ String.format("- 📨 exception Message: `%s`\n", exceptionMessage)
+ String.format("- 📋 meta: `%s`", meta == null ? "없음" : meta);
return String.format("⚠️ **알림 전송**\n- ⚠️ exception Cause : `%s`\n- 📨 exception Message: `%s`\n- 📋 meta: `%s`",
exceptionCause,
exceptionMessage,
meta == null ? "없음" : meta);

Expand Down