0

Is it's possible to throw an exception from the client to the server? We have an open stream from the server to the client:

rpc addStream(Request) returns (stream StreamMessage) {}     

When i try something like this:

throw Status.INTERNAL.withDescription(e.getMessage()).withCause(e.getCause()).asRuntimeException();

I got the exception in the StreamObserver.onError on the client, but there is no exception on the server-side.

1 Answer 1

1

Servers can respond with a "status" that the stub API exposes as a StatusRuntimeException. Clients, however, can only "cancel" the RPC. Servers will not know the source of the cancellation; it could be because the client cancelled or maybe the TCP connection broke.

In a client-streaming or bidi-streaming call, the client can cancel by calling observer.onError() (without ever calling onCompleted()). However, if the client called onCompleted() or the RPC has a unary request, then you need to use ClientCallStreamObserver or Context:

stub.someRpc(request, new ClientResponseObserver<Request, Response>() {
  private ClientCallStreamObserver<Request> requestStream;

  @Override public void beforeStart(ClientCallStreamObserver<Request> requestStream) {
    this.requestStream = requestStream;
  }
  ...
});

// And then where you want to cancel

// RequestStream is non-thread-safe. For unary requests, wait until
// stub.someRpc() returns, since it uses the stream internally.
// The string is not sent to the server. It is just "echoed"
// back to the client's `onError()` to make clear that the
// cancellation was locally caused.
requestStream.cancel("some message for yourself", null);


// For thread-safe cancellation (e.g., for client-streaming)
CancellableContext ctx = Context.current().withCancellation();
StreamObserver requestObserver = ctx.call(() ->
  stub.someRpc(new StreamObserver<Response>() {
    @Override public void onCompleted() {
      // The ctx must be closed when done, to avoid leaks
      ctx.cancel(null);
    }

    @Override public void onError() {
      ctx.cancel(null);
    }
  }));

// The place you want to cancel
ctx.cancel(ex);
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your answer. And how is this possible in server-streaming call?
@silb78, server-streaming has a single request, so it would be the same as for unary.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.