From 88a73af4aab18399dd51b30040ed1732d5dc65ca Mon Sep 17 00:00:00 2001 From: Gyoungmin Kim Date: Sat, 26 Oct 2024 06:58:21 +0900 Subject: [PATCH 1/2] feat: implement handlePhotoBrandNotExistsException in WebExceptionHandler --- .../photo/config/WebExceptionHandler.java | 21 +++++++++++++++++++ .../src/main/resources/application.yaml | 3 ++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/photo-service/src/main/java/kr/mafoo/photo/config/WebExceptionHandler.java b/photo-service/src/main/java/kr/mafoo/photo/config/WebExceptionHandler.java index fa97269..ad014e4 100644 --- a/photo-service/src/main/java/kr/mafoo/photo/config/WebExceptionHandler.java +++ b/photo-service/src/main/java/kr/mafoo/photo/config/WebExceptionHandler.java @@ -4,6 +4,7 @@ import kr.mafoo.photo.controller.dto.response.ErrorResponse; import kr.mafoo.photo.exception.DomainException; import kr.mafoo.photo.exception.ErrorCode; +import kr.mafoo.photo.exception.PhotoBrandNotExistsException; import kr.mafoo.photo.service.SlackService; import lombok.RequiredArgsConstructor; import org.slf4j.Logger; @@ -61,6 +62,26 @@ public ResponseEntity validException(Exception ex) { .body(response); } + @ExceptionHandler(PhotoBrandNotExistsException.class) + public Mono> handlePhotoBrandNotExistsException(ServerWebExchange exchange, PhotoBrandNotExistsException exception) { + String method = extractMethod(exchange); + String userAgent = extractUserAgent(exchange); + String fullPath = extractURI(exchange); + String originIp = extractOriginIp(exchange); + + return extractRequestBody(exchange).flatMap(requestBody -> { + logException(method, fullPath, originIp, userAgent, exception); + + return slackService.sendQrRelatedErrorNotification( + method, fullPath, requestBody, originIp, userAgent, exception.getMessage() + ).then(Mono.just( + ResponseEntity + .badRequest() + .body(ErrorResponse.fromErrorCode(exception.getErrorCode())) + )); + }); + } + @ExceptionHandler(ResponseStatusException.class) public Mono> handleResponseStatusException(ServerWebExchange exchange, ResponseStatusException exception) { return handleExceptionInternal(exchange, exception, (HttpStatus) exception.getStatusCode()); diff --git a/photo-service/src/main/resources/application.yaml b/photo-service/src/main/resources/application.yaml index 6e8f1c6..ec38138 100644 --- a/photo-service/src/main/resources/application.yaml +++ b/photo-service/src/main/resources/application.yaml @@ -46,4 +46,5 @@ slack: webhook: token: ${SLACK_TOKEN} channel: - error: ${SLACK_ERROR_CHANNEL} \ No newline at end of file + error: ${SLACK_ERROR_CHANNEL} + qr: ${SLACK_QR_ERROR_CHANNEL} \ No newline at end of file From 20b06b718a46d0d9da0cca9f66496f5cd969e5c6 Mon Sep 17 00:00:00 2001 From: Gyoungmin Kim Date: Sat, 26 Oct 2024 07:10:53 +0900 Subject: [PATCH 2/2] feat: create RequestBodyCachingFilter --- .../config/RequestBodyCachingFilter.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 photo-service/src/main/java/kr/mafoo/photo/config/RequestBodyCachingFilter.java diff --git a/photo-service/src/main/java/kr/mafoo/photo/config/RequestBodyCachingFilter.java b/photo-service/src/main/java/kr/mafoo/photo/config/RequestBodyCachingFilter.java new file mode 100644 index 0000000..5321ce6 --- /dev/null +++ b/photo-service/src/main/java/kr/mafoo/photo/config/RequestBodyCachingFilter.java @@ -0,0 +1,46 @@ +package kr.mafoo.photo.config; + +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.DataBufferUtils; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.http.server.reactive.ServerHttpRequestDecorator; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.ServerWebExchangeDecorator; +import org.springframework.web.server.WebFilter; +import org.springframework.web.server.WebFilterChain; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Component +public class RequestBodyCachingFilter implements WebFilter { + + // TODO: 추후 정리 필요 + + @Override + public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { + return DataBufferUtils.join(exchange.getRequest().getBody()) + .flatMap(dataBuffer -> { + byte[] bytes = new byte[dataBuffer.readableByteCount()]; + dataBuffer.read(bytes); + DataBufferUtils.release(dataBuffer); + + ServerHttpRequestDecorator decoratedRequest = new ServerHttpRequestDecorator(exchange.getRequest()) { + @Override + public Flux getBody() { + return Flux.just(exchange.getResponse().bufferFactory().wrap(bytes)); + } + }; + + ServerWebExchangeDecorator decoratedExchange = new ServerWebExchangeDecorator(exchange) { + @Override + public ServerHttpRequest getRequest() { + return decoratedRequest; + } + }; + + return chain.filter(decoratedExchange); + }); + } +} +