2016-09-30 20 views
6

Trong gRPC, làm cách nào để thêm trình chặn chặn ngoại lệ toàn cục chặn bất kỳ RuntimeException nào và truyền bá thông tin có ý nghĩa cho khách hàng? Ví dụ:Làm cách nào để thêm trình chặn chặn ngoại lệ toàn cầu vào máy chủ gRPC?

ví dụ: phương thức divide có thể ném ArithmeticException bằng thông báo / by zero. Trong phía máy chủ, tôi có thể viết:

@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(); 
} 

Nếu khách hàng qua mẫu số = 0, nó sẽ nhận được:

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

Và máy chủ kết quả đầu ra

Exception while executing runnable io.grpc.in[email protected]62e95ade 
java.lang.ArithmeticException:/by zero 

Client doesn' Tôi biết chuyện gì đang xảy ra.

Nếu tôi muốn vượt qua / by zero thông điệp tới khách hàng, tôi phải thay đổi máy chủ để: (như mô tả trong question này)

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()))); 
    } 

Và nếu khách hàng gửi mẫu số = 0, nó sẽ nhận được:

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

Tốt, / by zero được chuyển cho khách hàng. Nhưng vấn đề là, trong một môi trường doanh nghiệp thực sự, sẽ có rất nhiều RuntimeException s, và nếu tôi muốn truyền các thông điệp ngoại lệ này cho khách hàng, tôi sẽ phải cố gắng nắm bắt từng phương pháp, rất cồng kềnh.

Có máy đánh chặn toàn cầu nào chặn mọi phương thức, bắt RuntimeException và kích hoạt onError và truyền bá thông báo lỗi cho khách hàng không? Vì vậy, tôi không phải đối phó với RuntimeException s trong mã máy chủ của tôi.

Cảm ơn rất nhiều!

Lưu ý:

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

Trả lời

0
public class GrpcExceptionHandler implements ServerInterceptor { 

private final Logger logger = LoggerFactory.getLogger (GrpcExceptionHandler.class); 

@Override 
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall (ServerCall<ReqT, RespT> call, 
                   Metadata headers, 
                   ServerCallHandler<ReqT, RespT> next) { 
    logger.info ("GRPC call at: {}", Instant.now()); 
    ServerCall.Listener<ReqT> listener; 

    try { 
     listener = next.startCall (call, headers); 
    } catch (Throwable ex) { 
     logger.error ("Uncaught exception from grpc service"); 
     call.close (Status.INTERNAL 
       .withCause (ex) 
       .withDescription ("Uncaught exception from grpc service"), null); 
     return new ServerCall.Listener<ReqT>() {}; 
    } 

    return listener; 
} 

}

mẫu đánh chặn trên.

Bạn cần phải khởi động nó, tất nhiên, trước khi mong đợi bất cứ điều gì từ nó;

serverBuilder.addService (ServerInterceptors.intercept (bindableService, interceptor)); 

Cập nhật:

public interface ServerCallHandler<RequestT, ResponseT> { 
    /** 
    * Produce a non-{@code null} listener for the incoming call. Implementations are free to call 
    * methods on {@code call} before this method has returned. 
    * 
    * <p>If the implementation throws an exception, {@code call} will be closed with an error. 
    * Implementations must not throw an exception if they started processing that may use {@code 
    * call} on another thread. 
    * 
    * @param call object for responding to the remote client. 
    * @return listener for processing incoming request messages for {@code call} 
    */ 
    ServerCall.Listener<RequestT> startCall(
     ServerCall<RequestT, ResponseT> call, 
     Metadata headers); 
} 

Đáng buồn là, khác với bối cảnh thread có nghĩa là không xử lý phạm vi ngoại lệ, vì vậy câu trả lời của tôi không phải là giải pháp bạn đang tìm kiếm ..

+0

Xin lỗi, nó không hoạt động. Dòng này 'logger.error (" Ngoại lệ không bắt buộc từ dịch vụ grpc ");' không đạt được! Tôi cũng cảm thấy kỳ lạ. – smallufo

+0

Bạn có muốn chia sẻ mã của mình không? – Gladmir

+0

mã ở đây, FYI: http://pastebin.com/a96suWB1 – smallufo

0

Có bạn đọc java grpc examples cho máy đánh chặn?

Vì vậy, trong trường hợp của mình, chúng tôi sử dụng mã và thông báo làm chuẩn để xác định loại lỗi máy chủ được gửi tới máy khách.

Ví dụ: máy chủ gửi phản ứng như

{ 
    code: 409, 
    message: 'Id xxx aldready exist' 
} 

Vì vậy, trong các khách hàng mà bạn có thể đánh chặn cài đặt client để nhận mã và đáp ứng với Reflection. Fyi chúng tôi sử dụng Lognet Spring Boot starter for grpc làm máy chủ và khởi động Spring cho máy khách.

Các vấn đề liên quan