gpt4 book ai didi

java - 如何在 gRPC 服务器中添加全局异常拦截器?

转载 作者:太空狗 更新时间:2023-10-29 22:41:36 28 4
gpt4 key购买 nike

在 gRPC 中,如何添加一个全局异常拦截器来拦截任何 RuntimeException 并将有意义的信息传播给客户端?

例如,divide 方法可能会抛出 ArithmeticException/by zero 消息。在服务器端,我可能会写:

@Override
public void divide(DivideRequest request, StreamObserver<DivideResponse> responseObserver) {
int dom = request.getDenominator();
int num = request.getNumerator();

double result = num / dom;
responseObserver.onNext(DivideResponse.newBuilder().setValue(result).build());
responseObserver.onCompleted();
}

如果客户端传递 denominator = 0 ,它将得到:

Exception in thread "main" io.grpc.StatusRuntimeException: UNKNOWN

然后服务器输出

Exception while executing runnable io.grpc.internal.ServerImpl$JumpToApplicationThreadServerStreamListener$2@62e95ade
java.lang.ArithmeticException: / by zero

客户不知道发生了什么。

如果我想将 /by zero 消息传递给客户端,我必须将服务器修改为:(如本 question 中所述)

  try {
double result = num / dom;
responseObserver.onNext(DivideResponse.newBuilder().setValue(result).build());
responseObserver.onCompleted();
} catch (Exception e) {
logger.error("onError : {}" , e.getMessage());
responseObserver.onError(new StatusRuntimeException(Status.INTERNAL.withDescription(e.getMessage())));
}

如果客户端发送 denominator = 0 ,它将得到:

Exception in thread "main" io.grpc.StatusRuntimeException: INTERNAL: / by zero

好的,/由零传递给客户端。

但问题是,在真正的企业环境中,会有很多RuntimeException,如果我想将这些异常消息传递给客户端,我将不得不 try catch 每个方法,这非常麻烦。

是否有任何全局拦截器拦截每个方法,捕获 RuntimeException 并触发 onError 并将错误消息传播到客户端?这样我就不必在服务器代码中处理 RuntimeException

非常感谢!

注意:

<grpc.version>1.0.1</grpc.version>
com.google.protobuf:proton:3.1.0
io.grpc:protoc-gen-grpc-java:1.0.1

最佳答案

下面的代码将捕获所有运行时异常,另请参阅链接 https://github.com/grpc/grpc-java/issues/1552

public class GlobalGrpcExceptionHandler implements ServerInterceptor {

@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call,
Metadata requestHeaders, ServerCallHandler<ReqT, RespT> next) {
ServerCall.Listener<ReqT> delegate = next.startCall(call, requestHeaders);
return new SimpleForwardingServerCallListener<ReqT>(delegate) {
@Override
public void onHalfClose() {
try {
super.onHalfClose();
} catch (Exception e) {
call.close(Status.INTERNAL
.withCause (e)
.withDescription("error message"), new Metadata());
}
}
};
}
}

关于java - 如何在 gRPC 服务器中添加全局异常拦截器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39797142/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com