类似于spring mvc全局捕获异常,然后统一返回错误信息;我们尝试在Grpc中实现类似方案:
@GrpcGlobalServerInterceptor
public class GrpcGlobalInterceptor implements ServerInterceptor {
@Override
public <ReqT, RespT> Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall, Metadata metadata,
ServerCallHandler<ReqT, RespT> serverCallHandler) {
Listener<ReqT> listener = serverCallHandler.startCall(serverCall, metadata);
return new HandlingServerCallListener<ReqT, RespT>(listener, serverCall, metadata);
}
private class HandlingServerCallListener<ReqT, RespT> extends SimpleForwardingServerCallListener<ReqT> {
private ServerCall<ReqT, RespT> serverCall;
private Metadata metadata;
HandlingServerCallListener(Listener<ReqT> listener, ServerCall<ReqT, RespT> serverCall, Metadata metadata) {
super(listener);
this.serverCall = serverCall;
this.metadata = metadata;
}
public void onHalfClose() {
try {
super.onHalfClose();
} catch (RuntimeException e) {
RespT resp = (RespT) AccountResponse.newBuilder()
.setCode(AccountNotFound.getCode())
.setMessage(e.getMessage())
.build();
serverCall.sendHeaders(metadata);
serverCall.sendMessage(resp);
serverCall.close(Status.OK, metadata);
}
}
}
}
非标准用法,慎重使用;建议通过 @ClientInterceptor 或 手动try-catch 在客户端拦截异常来进行处理;