diff --git a/src/main/java/com/doubleo/memberservice/domain/member/grpc/server/MemberGrpcServiceImpl.java b/src/main/java/com/doubleo/memberservice/domain/member/grpc/server/MemberGrpcServiceImpl.java index 3258bb3..7b25f02 100644 --- a/src/main/java/com/doubleo/memberservice/domain/member/grpc/server/MemberGrpcServiceImpl.java +++ b/src/main/java/com/doubleo/memberservice/domain/member/grpc/server/MemberGrpcServiceImpl.java @@ -1,7 +1,7 @@ package com.doubleo.memberservice.domain.member.grpc.server; import com.doubleo.memberservice.domain.member.repository.MemberRepository; -import com.doubleo.memberservice.global.exception.CommonException; +import com.doubleo.memberservice.global.exception.GrpcExceptionUtil; import com.doubleo.memberservice.global.exception.errorcode.MemberErrorCode; import io.grpc.stub.StreamObserver; import net.devh.boot.grpc.server.service.GrpcService; @@ -34,6 +34,7 @@ public void getMember(MemberRequest request, StreamObserver resp }, () -> responseObserver.onError( - new CommonException(MemberErrorCode.MEMBER_NOT_FOUND))); + GrpcExceptionUtil.toStatusRuntimeException( + MemberErrorCode.MEMBER_NOT_FOUND))); } } diff --git a/src/main/java/com/doubleo/memberservice/global/exception/GrpcExceptionUtil.java b/src/main/java/com/doubleo/memberservice/global/exception/GrpcExceptionUtil.java new file mode 100644 index 0000000..f6e1a96 --- /dev/null +++ b/src/main/java/com/doubleo/memberservice/global/exception/GrpcExceptionUtil.java @@ -0,0 +1,44 @@ +package com.doubleo.memberservice.global.exception; + +import com.doubleo.memberservice.global.exception.errorcode.BaseErrorCode; +import com.doubleo.memberservice.global.exception.errorcode.ErrorCodeRegistry; +import com.doubleo.memberservice.global.exception.errorcode.GrpcErrorCode; +import io.grpc.Metadata; +import io.grpc.Status; +import io.grpc.StatusRuntimeException; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class GrpcExceptionUtil { + + private static final Metadata.Key CODE_KEY = + Metadata.Key.of("code", Metadata.ASCII_STRING_MARSHALLER); + private static final Metadata.Key CLASS_KEY = + Metadata.Key.of("class", Metadata.ASCII_STRING_MARSHALLER); + private static final Metadata.Key MESSAGE_KEY = + Metadata.Key.of("message", Metadata.ASCII_STRING_MARSHALLER); + + public static StatusRuntimeException toStatusRuntimeException(BaseErrorCode errorCode) { + Metadata metadata = new Metadata(); + metadata.put(CODE_KEY, errorCode.errorClassName()); + metadata.put(CLASS_KEY, errorCode.getClass().getSimpleName()); + metadata.put(MESSAGE_KEY, errorCode.getMessage()); + + return Status.fromCodeValue(errorCode.getHttpStatus().value()) + .withDescription(errorCode.getMessage()) + .asRuntimeException(metadata); + } + + public static CommonException fromStatusRuntimeException(StatusRuntimeException e) { + Metadata metadata = Status.trailersFromThrowable(e); + if (metadata != null) { + String code = metadata.get(CODE_KEY); + String className = metadata.get(CLASS_KEY); + String message = metadata.get(MESSAGE_KEY); + + log.warn("gRPC Error - code: {}, message: {}", code, message); + return new CommonException(ErrorCodeRegistry.resolve(className, code)); + } + return new CommonException(GrpcErrorCode.GRPC_SERVER_RESPONSE_FAILED); + } +} diff --git a/src/main/java/com/doubleo/memberservice/global/exception/errorcode/ErrorCodeRegistry.java b/src/main/java/com/doubleo/memberservice/global/exception/errorcode/ErrorCodeRegistry.java new file mode 100644 index 0000000..f397a6f --- /dev/null +++ b/src/main/java/com/doubleo/memberservice/global/exception/errorcode/ErrorCodeRegistry.java @@ -0,0 +1,29 @@ +package com.doubleo.memberservice.global.exception.errorcode; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +public class ErrorCodeRegistry { + private static final Map> registry = + new HashMap<>(); + + static { + registry.put("GlobalErrorCode", GlobalErrorCode::valueOf); + registry.put("GrpcErrorCode", GrpcErrorCode::valueOf); + registry.put("MemberErrorCode", MemberErrorCode::valueOf); + } + + public static BaseErrorCode resolve(String className, String code) { + Function parser = registry.get(className); + if (parser == null) { + throw new IllegalArgumentException("Unknown class " + className); + } + try { + return parser.apply(code); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException( + "Invalid error code " + code + " for class " + className, e); + } + } +} diff --git a/src/main/java/com/doubleo/memberservice/global/exception/errorcode/GrpcErrorCode.java b/src/main/java/com/doubleo/memberservice/global/exception/errorcode/GrpcErrorCode.java new file mode 100644 index 0000000..416f876 --- /dev/null +++ b/src/main/java/com/doubleo/memberservice/global/exception/errorcode/GrpcErrorCode.java @@ -0,0 +1,20 @@ +package com.doubleo.memberservice.global.exception.errorcode; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public enum GrpcErrorCode implements BaseErrorCode { + GRPC_SERVER_RESPONSE_FAILED(HttpStatus.NOT_FOUND, "gRPC 호출에 실패했습니다."), + ; + + private final HttpStatus httpStatus; + private final String message; + + @Override + public String errorClassName() { + return this.name(); + } +}