diff --git a/stub/src/main/java/io/grpc/stub/ClientCalls.java b/stub/src/main/java/io/grpc/stub/ClientCalls.java index ff2804a0a1f..5fcb1d42d78 100644 --- a/stub/src/main/java/io/grpc/stub/ClientCalls.java +++ b/stub/src/main/java/io/grpc/stub/ClientCalls.java @@ -77,6 +77,12 @@ private ClientCalls() {} * *

If the provided {@code responseObserver} is an instance of {@link ClientResponseObserver}, * {@code beforeStart()} will be called. + * + *

Server errors

+ * If the server completes the RPC with status code OK, then {@code + * responseObserver.onCompleted()} is called at the end of the RPC. Otherwise the status and + * trailers are passed as a Throwable to {@code onError()} and can be accessed with {@link + * Status#fromThrowable} and {@link Status#trailersFromThrowable}. */ public static void asyncUnaryCall( ClientCall call, ReqT req, StreamObserver responseObserver) { @@ -91,6 +97,12 @@ public static void asyncUnaryCall( * *

If the provided {@code responseObserver} is an instance of {@link ClientResponseObserver}, * {@code beforeStart()} will be called. + * + *

Server errors

+ * If the server completes the RPC with status code OK, then {@code + * responseObserver.onCompleted()} is called at the end of the RPC. Otherwise the status and + * trailers are passed as a Throwable to {@code onError()} and can be accessed with {@link + * Status#fromThrowable} and {@link Status#trailersFromThrowable}. */ public static void asyncServerStreamingCall( ClientCall call, ReqT req, StreamObserver responseObserver) { @@ -106,6 +118,25 @@ public static void asyncServerStreamingCall( *

If the provided {@code responseObserver} is an instance of {@link ClientResponseObserver}, * {@code beforeStart()} will be called. * + *

Client errors

+ * {@link StreamObserver#onError} called on the request stream observer will result in stream + * cancellation. The response + * {@link StreamObserver} will be immediately notified of the cancellation with a + * {@link io.grpc.StatusRuntimeException} with the exception passed to onError set as the cause + * and the stream is considered closed. The server's request stream observer will receive an + * {@link StreamObserver#onError} callback with a throwable which when converted to a status + * with + * Status.fromThrowable(), always has the status code CANCELLED and exception cause set to + * null because the actual exception + * passed by the client to onError is never actually transmitted to the server and the server + * just receives a RST_STREAM frame indicating cancellation by the client. + * + *

Server errors

+ * If the server completes the RPC with status code OK, then {@code + * responseObserver.onCompleted()} is called at the end of the RPC. Otherwise the status and + * trailers are passed as a Throwable to {@code onError()} and can be accessed with {@link + * Status#fromThrowable} and {@link Status#trailersFromThrowable}. + * * @return request stream observer. It will extend {@link ClientCallStreamObserver} */ public static StreamObserver asyncClientStreamingCall( @@ -122,6 +153,25 @@ public static StreamObserver asyncClientStreamingCall( *

If the provided {@code responseObserver} is an instance of {@link ClientResponseObserver}, * {@code beforeStart()} will be called. * + *

Client errors

+ * {@link StreamObserver#onError} called on the request stream observer will result in stream + * cancellation. The response + * {@link StreamObserver} will be immediately notified of the cancellation with a + * {@link io.grpc.StatusRuntimeException} with the exception passed to onError set as the cause + * and the stream is considered closed. The server's request stream observer will receive an + * {@link StreamObserver#onError} callback with a throwable which when converted to a status + * with + * Status.fromThrowable(), always has the status code CANCELLED and exception cause set to + * null because the actual exception + * passed by the client to onError is never actually transmitted to the server and the server + * just receives a RST_STREAM frame indicating cancellation by the client. + * + *

Server errors

+ * If the server completes the RPC with status code OK, then {@code + * responseObserver.onCompleted()} is called at the end of the RPC. Otherwise the status and + * trailers are passed as a Throwable to {@code onError()} and can be accessed with {@link + * Status#fromThrowable} and {@link Status#trailersFromThrowable}. + * * @return request stream observer. It will extend {@link ClientCallStreamObserver} */ public static StreamObserver asyncBidiStreamingCall( @@ -134,6 +184,10 @@ public static StreamObserver asyncBidiStreamingCall( * Executes a unary call and blocks on the response. The {@code call} should not be already * started. After calling this method, {@code call} should no longer be used. * + *

Server errors

+ * If the server completes the RPC with a non-OK status, a {@link StatusRuntimeException} + * is thrown. The status code and trailers can be accessed from the exception. + * * @return the single response message. * @throws StatusRuntimeException on error */ @@ -149,6 +203,10 @@ public static RespT blockingUnaryCall(ClientCall call * Executes a unary call and blocks on the response. The {@code call} should not be already * started. After calling this method, {@code call} should no longer be used. * + *

Server errors

+ * If the server completes the RPC with a non-OK status, a {@link StatusRuntimeException} + * is thrown. The status code and trailers can be accessed from the exception. + * * @return the single response message. * @throws StatusRuntimeException on error */ @@ -186,6 +244,10 @@ public static RespT blockingUnaryCall( * Executes a unary call and blocks on the response, * throws a checked {@link StatusException}. * + *

Server errors

+ * If the server completes the RPC with a non-OK status, a {@link StatusException} + * is thrown. The status code and trailers can be accessed from the exception. + * * @return the single response message. * @throws StatusException on error */ @@ -204,7 +266,11 @@ public static RespT blockingV2UnaryCall( * response stream. The {@code call} should not be already started. After calling this method, * {@code call} should no longer be used. * - *

The returned iterator may throw {@link StatusRuntimeException} on error. + *

Server errors

+ * If the server completes the RPC with a non-OK status, the returned iterator will throw + * a {@link StatusRuntimeException} when attempting to read the error response (e.g. in + * {@link Iterator#hasNext} or {@link Iterator#next}). The status code and trailers can be + * accessed from the exception. * * @return an iterator over the response stream. */ @@ -219,7 +285,11 @@ public static Iterator blockingServerStreamingCall( * Executes a server-streaming call returning a blocking {@link Iterator} over the * response stream. * - *

The returned iterator may throw {@link StatusRuntimeException} on error. + *

Server errors

+ * If the server completes the RPC with a non-OK status, the returned iterator will throw + * a {@link StatusRuntimeException} when attempting to read the error response (e.g. in + * {@link Iterator#hasNext} or {@link Iterator#next}). The status code and trailers can be + * accessed from the exception. * *

Warning: the iterator can result in leaks if not completely consumed. * @@ -242,6 +312,13 @@ public static Iterator blockingServerStreamingCall( *

The methods {@link BlockingClientCall#hasNext()} and {@link * BlockingClientCall#cancel(String, Throwable)} can be used for more extensive control. * + *

Server errors

+ * If the server completes the RPC with a non-OK status, the returned {@link BlockingClientCall} + * will throw a {@link StatusException} when calling read or write operations (e.g., + * {@link BlockingClientCall#read()}, {@link BlockingClientCall#hasNext()}, or + * {@link BlockingClientCall#write(Object)}). The status code and trailers can be accessed from + * the exception. + * * @return A {@link BlockingClientCall} that has had the request sent and halfClose called */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918") @@ -280,6 +357,13 @@ public static BlockingClientCall blockingV2ServerStre * {@link #blockingServerStreamingCall(Channel, MethodDescriptor, CallOptions, Object)} * which returns an iterator, which would leave the stream open if not completely consumed. * + *

Server errors

+ * If the server completes the RPC with a non-OK status, the returned {@link BlockingClientCall} + * will throw a {@link StatusException} when calling read or write operations (e.g., + * {@link BlockingClientCall#read()}, {@link BlockingClientCall#hasNext()}, or + * {@link BlockingClientCall#write(Object)}). The status code and trailers can be accessed from + * the exception. + * * @return A {@link BlockingClientCall} which can be used by the client to write and receive * messages over the grpc channel. */ @@ -294,6 +378,13 @@ public static BlockingClientCall blockingClientStream * ({@link BlockingClientCall}) which can be used by the client to send and receive messages over * the grpc channel. * + *

Server errors

+ * If the server completes the RPC with a non-OK status, the returned {@link BlockingClientCall} + * will throw a {@link StatusException} when calling read or write operations (e.g., + * {@link BlockingClientCall#read()}, {@link BlockingClientCall#hasNext()}, or + * {@link BlockingClientCall#write(Object)}). The status code and trailers can be accessed from + * the exception. + * * @return an object representing the call which can be used to read, write and terminate it. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918") @@ -316,6 +407,11 @@ public static BlockingClientCall blockingBidiStreamin * {@code call} should not be already started. After calling this method, {@code call} should no * longer be used. * + *

Server errors

+ * If the server completes the RPC with a non-OK status, the returned future will fail with + * a {@link StatusRuntimeException}. The status code and trailers can be accessed from the + * exception. + * * @return a future for the single response message. */ public static ListenableFuture futureUnaryCall( diff --git a/stub/src/main/java/io/grpc/stub/ServerCalls.java b/stub/src/main/java/io/grpc/stub/ServerCalls.java index 9f0063713cc..6780b425525 100644 --- a/stub/src/main/java/io/grpc/stub/ServerCalls.java +++ b/stub/src/main/java/io/grpc/stub/ServerCalls.java @@ -85,6 +85,20 @@ public static ServerCallHandler asyncBidiStreamingCal * Adaptor to a unary call method. */ public interface UnaryMethod extends UnaryRequestMethod { + /** + * Invoke the method. + * + * @param request the request message from the client + * @param responseObserver the observer to receive the single response. Calling {@code + * responseObserver}'s {@link StreamObserver#onCompleted} or {@link + * StreamObserver#onError} is the end of the RPC. {@code onCompleted()} will close the RPC + * with status code OK. {@code onError()} will convert the Throwable to a Status with {@link + * Status#fromThrowable} and trailers with {@link Status#trailersFromThrowable}. The {@link + * Status#getCause} is not sent to the client, except if done by an interceptor. Callers + * generally create a Throwable with {@link Status#asException()}, {@link + * Status#asException(Metadata)}, {@link Status#asRuntimeException()}, or {@link + * Status#asRuntimeException(Metadata)}. + */ @Override void invoke(ReqT request, StreamObserver responseObserver); } @@ -92,6 +106,20 @@ public interface UnaryMethod extends UnaryRequestMethod extends UnaryRequestMethod { + /** + * Invoke the method. + * + * @param request the request message from the client + * @param responseObserver the observer to receive the response stream. Calling {@code + * responseObserver}'s {@link StreamObserver#onCompleted} or {@link + * StreamObserver#onError} is the end of the RPC. {@code onCompleted()} will close the RPC + * with status code OK. {@code onError()} will convert the Throwable to a Status with {@link + * Status#fromThrowable} and trailers with {@link Status#trailersFromThrowable}. The {@link + * Status#getCause} is not sent to the client, except if done by an interceptor. Callers + * generally create a Throwable with {@link Status#asException()}, {@link + * Status#asException(Metadata)}, {@link Status#asRuntimeException()}, or {@link + * Status#asRuntimeException(Metadata)}. + */ @Override void invoke(ReqT request, StreamObserver responseObserver); } @@ -99,6 +127,24 @@ public interface ServerStreamingMethod extends UnaryRequestMethod extends StreamingRequestMethod { + /** + * Invoke the method. + * + *

Client errors

+ * The Throwable received by the server's request stream observer when converted to a status + * with Status.fromThrowable(), always has the status code CANCELLED. + * + * @param responseObserver the observer to receive the single response. Calling {@code + * responseObserver}'s {@link StreamObserver#onCompleted} or {@link + * StreamObserver#onError} is the end of the RPC. {@code onCompleted()} will close the RPC + * with status code OK. {@code onError()} will convert the Throwable to a Status with {@link + * Status#fromThrowable} and trailers with {@link Status#trailersFromThrowable}. The {@link + * Status#getCause} is not sent to the client, except if done by an interceptor. Callers + * generally create a Throwable with {@link Status#asException()}, {@link + * Status#asException(Metadata)}, {@link Status#asRuntimeException()}, or {@link + * Status#asRuntimeException(Metadata)}. + * @return a stream observer for receiving the request stream from the client + */ @Override StreamObserver invoke(StreamObserver responseObserver); } @@ -106,6 +152,24 @@ public interface ClientStreamingMethod extends StreamingRequestMeth * Adaptor to a bidirectional streaming method. */ public interface BidiStreamingMethod extends StreamingRequestMethod { + /** + * Invoke the method. + * + *

Client errors

+ * The Throwable received by the server's request stream observer when converted to a status + * with Status.fromThrowable(), always has the status code CANCELLED. + * + * @param responseObserver the observer to receive the response stream. Calling {@code + * responseObserver}'s {@link StreamObserver#onCompleted} or {@link + * StreamObserver#onError} is the end of the RPC. {@code onCompleted()} will close the RPC + * with status code OK. {@code onError()} will convert the Throwable to a Status with {@link + * Status#fromThrowable} and trailers with {@link Status#trailersFromThrowable}. The {@link + * Status#getCause} is not sent to the client, except if done by an interceptor. Callers + * generally create a Throwable with {@link Status#asException()}, {@link + * Status#asException(Metadata)}, {@link Status#asRuntimeException()}, or {@link + * Status#asRuntimeException(Metadata)}. + * @return a stream observer for receiving the request stream from the client + */ @Override StreamObserver invoke(StreamObserver responseObserver); }