Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
74 views
in Technique[技术] by (71.8m points)

java - Handling exceptions in gRPC

I'm having some trouble with getting my gRPC endpoint working as expected, I've simplified my code to illustrate the issue I'm having. Essentially, I can't get the code in the exceptionally body to execute and I can't figure out why, it always seems to return a Status with code UNKNOWN but I'm expecting it to return INVALID_ARGUMENT as that's what I'm throwing in the GetNamesService class. The System.out.println in the exceptionally clause also doesn't print.

public class GrpcService extends GrpcServiceImplBase {

  private final GetNamesService getNamesService;

  public GrpcService(GetNamesService getNamesService) {
    this.getNamesService = getNamesService;
  }

  @Override
  public void getNames(NameRequest request, StreamObserver<NameResponse> responseObserver) {
    getNamesService.getNames(request)
       .thenAccept(r -> {
          responseObserver.onNext(r);
          responseObserver.onCompleted();
       })
       .exceptionally(t -> {
          System.out.println("About to handle the exception");
          responseObserver.onError(handleException(t));
       });
  }

  private StatusRuntimeException handleException(Throwable t) {
    if (t instanceof CompletionException) {
      return handleException(t.getCause());
    }

    if (t instanceof StatusRuntimeException) {
      var statusException = (StatusRuntimeException) t;
      return statusException;
    }

    return Status.UNKNOWN.withDescription(t.getMessage()).asRuntimeException();
  }
}

public class GetNamesService {

  public CompletionStage<NameResponse> getNames(NameRequest request) {
    
    // Just throwing an exception to try and get error handling to work
    throw Status.INVALID_ARGUMENT
        .withDescription("Invalid request")
        .asRuntimeException();
  }

}
question from:https://stackoverflow.com/questions/65838675/handling-exceptions-in-grpc

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

In this block of fluent-style code:

getNamesService.getNames(request)
   .thenAccept(r -> {
      responseObserver.onNext(r);
      responseObserver.onCompleted();
   })
   .exceptionally(t -> {
      System.out.println("About to handle the exception");
      responseObserver.onError(handleException(t));
   });

If this entire block runs, getNamesService.getNames(request) is called, and the return value from that method is an object that contains a thenAccept method. That method is then called, and it returns an object that contains an exceptionally method. Finally, that exceptionally method is called.

There is no magic here. This is just plain old Python. This chain works because each method call returns an object that contains a method such that the next method call in the chain is valid. If a method in the chain throws an exception instead of returning an object containing the next method in the chain, the rest of the chain isn't executed.

When getNamesService.getNames(request) is called and throws an exception, the remaining methods in the chain, thenAccept and exceptionally, are not executed, and so there's no reason to expect that the System.out.println in the block will be called.

For the code you supplied, getNamesService.getNames(request) always throws an exception, and so the complicated code block above is equivalent in function to just:

getNamesService.getNames(request)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...