Skip to content

Commit

Permalink
#578 [feat] 메신저 이관으로 메시지 전송 모듈 구현
Browse files Browse the repository at this point in the history
#578 [feat] 메신저 이관으로 메시지 전송 모듈 구현
  • Loading branch information
sohyundoh authored Nov 17, 2024
2 parents c89bfb1 + c0820be commit a8f9936
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.mile.exception.model.NotFoundException;
import com.mile.exception.model.TooManyRequestException;
import com.mile.exception.model.UnauthorizedException;
import com.mile.slack.module.SendErrorModule;
import io.sentry.Sentry;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -31,22 +32,25 @@
public class GlobalExceptionHandler {

private static final int INDEX_ZERO = 0;
private final SendErrorModule sendErrorModule;

public GlobalExceptionHandler(SendErrorModule sendErrorModule) {
this.sendErrorModule = sendErrorModule;
}

@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<ErrorResponse> handleHttpMessageNotReadableException(final HttpMessageNotReadableException e) {
Sentry.captureException(e);
;
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ErrorResponse.of(ErrorMessage.ENUM_VALUE_BAD_REQUEST));
}

@ExceptionHandler(HandlerMethodValidationException.class)
public ResponseEntity<ErrorResponse> handleHandlerMethodValidationException(final HandlerMethodValidationException e) {
Sentry.captureException(e);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ErrorResponse.of(HttpStatus.BAD_REQUEST.value(), Objects.requireNonNull(e.getAllValidationResults().get(INDEX_ZERO).getResolvableErrors().get(INDEX_ZERO).getDefaultMessage())));
}

@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public ResponseEntity<ErrorResponse> handleMethodArgumentTypeMismatchException(final MethodArgumentTypeMismatchException e) {
Sentry.captureException(e);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ErrorResponse.of(ErrorMessage.REQUEST_URL_WRONG_ERROR));
}

Expand All @@ -58,13 +62,11 @@ public ResponseEntity<ErrorResponse> handleBadRequestException(final BadRequestE

@ExceptionHandler(UnauthorizedException.class)
public ResponseEntity<ErrorResponse> handleUnauthorizedException(final UnauthorizedException e) {
Sentry.captureException(e);
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(ErrorResponse.of(e.getErrorMessage()));
}

@ExceptionHandler(JwtValidationException.class)
public ResponseEntity<ErrorResponse> handleJwtValidationException(final JwtValidationException e) {
Sentry.captureException(e);
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(ErrorResponse.of(e.getErrorMessage()));
}

Expand Down Expand Up @@ -92,25 +94,21 @@ protected ResponseEntity<ErrorResponse> handleMethodArgumentNotValidException(fi

@ExceptionHandler(ForbiddenException.class)
public ResponseEntity<ErrorResponse> handleForbiddenException(final ForbiddenException e) {
Sentry.captureException(e);
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(ErrorResponse.of(e.getErrorMessage()));
}

@ExceptionHandler(NotFoundException.class)
public ResponseEntity<ErrorResponse> handleNotFoundException(final NotFoundException e) {
Sentry.captureException(e);
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ErrorResponse.of(e.getErrorMessage()));
}

@ExceptionHandler(ConflictException.class)
public ResponseEntity<ErrorResponse> handleConflictException(final ConflictException e) {
Sentry.captureException(e);
return ResponseEntity.status(HttpStatus.CONFLICT).body(ErrorResponse.of(e.getErrorMessage()));
}

@ExceptionHandler(TooManyRequestException.class)
public ResponseEntity<ErrorResponse> handleTooManyRequestException(final TooManyRequestException e) {
Sentry.captureException(e);
return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).body(ErrorResponse.of(e.getErrorMessage()));
}

Expand All @@ -121,7 +119,8 @@ public ResponseEntity<ErrorResponse> handleNoHandlerFoundException(final NoHandl

@ExceptionHandler(Exception.class)
protected ResponseEntity<ErrorResponse> handleException(final Exception error, final HttpServletRequest request) {
Sentry.captureException(error);
sendErrorModule.sendError(error);

log.error("================================================NEW===============================================");
log.error(error.getMessage(), error);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ErrorResponse.of(ErrorMessage.INTERNAL_SERVER_ERROR));
Expand Down
3 changes: 0 additions & 3 deletions module-domain/src/main/java/com/mile/common/CacheService.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.mile.common;

import com.mile.slack.module.SendMessageModule;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;
Expand All @@ -11,10 +10,8 @@ public class CacheService {

private final String MOIM_CACHE_NAME = "moimPopularInfo";
private final CacheManager cacheManager;
private final SendMessageModule sendMessageModule;

public void deleteMoimCache() {
sendMessageModule.sendMessage("INTERNAL API 호출) 글모임 별 인기 글/ 작가에 대한 캐시 삭제 완료");
if (cacheManager.getCache(MOIM_CACHE_NAME) != null) {
cacheManager.getCache(MOIM_CACHE_NAME).clear();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.mile.slack.module;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;

@Slf4j
@Component
public class SendErrorModule extends SendWebhookMessage {
private final StringBuilder sb = new StringBuilder();

@Value("${webhook.url-for-error}")
private String webHookUri;

@Value("${spring.profiles.active}")
private String profile;

@Override
public void sendError(@NonNull final Exception exception) {
WebClient webClient = WebClient.builder()
.baseUrl(webHookUri).build();


webClient.post()
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(generateMessage(exception))
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(String.class)
.doOnError(e -> log.error("WEB HOOK 전송 중 에러 발생 -> {}", e.getMessage()))
.subscribe();
}


private String readRootStackTrace(Exception error) {
return error.getStackTrace()[0].toString();
}

private Message generateMessage(final Exception exception) {
sb.append("🚨 ERROR🚨").append("\n").append(exception.toString()).append("\n").append("\n");
sb.append("🏃🏻PROFILE🏃🏻").append("\n").append(profile).append("\n").append("\n");
sb.append("🆔REQUEST ID🆔").append("\n").append(MDC.get("request_id")).append("\n").append("\n");
sb.append("️✏️DETAILS✏️").append("\n").append(readRootStackTrace(exception)).append("\n");

return new Message(sb.toString());
}

@Getter
@AllArgsConstructor
private class Message {
private String text;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

@Component
@Slf4j
public class SendMessageModule implements SendWebhookMessage {
public class SendMessageModule extends SendWebhookMessage {
private final StringBuilder sb = new StringBuilder();

@Value("${webhook.url-for-event}")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.mile.slack.module;

import org.springframework.lang.NonNull;

public interface SendWebhookMessage {
void sendMessage(@NonNull final String message);

public abstract class SendWebhookMessage {
void sendMessage(String message) {
// TODO() - 상속받아 구현하기
}
void sendError(Exception exception){
// TODO() - 상속받아 구현하기
}
}

0 comments on commit a8f9936

Please sign in to comment.