diff --git a/core/src/main/java/io/grpc/internal/ServerCallImpl.java b/core/src/main/java/io/grpc/internal/ServerCallImpl.java index 7555c4d78a..08aff5f038 100644 --- a/core/src/main/java/io/grpc/internal/ServerCallImpl.java +++ b/core/src/main/java/io/grpc/internal/ServerCallImpl.java @@ -41,6 +41,7 @@ import io.grpc.MethodDescriptor; import io.grpc.SecurityLevel; import io.grpc.ServerCall; import io.grpc.Status; +import io.grpc.StatusRuntimeException; import io.perfmark.PerfMark; import io.perfmark.Tag; import io.perfmark.TaskCloseable; @@ -157,7 +158,7 @@ final class ServerCallImpl extends ServerCall { checkState(!closeCalled, "call is closed"); if (method.getType().serverSendsOneMessage() && messageSent) { - internalClose(Status.INTERNAL.withDescription(TOO_MANY_RESPONSES)); + handleInternalError(Status.INTERNAL.withDescription(TOO_MANY_RESPONSES).asRuntimeException()); return; } @@ -169,7 +170,7 @@ final class ServerCallImpl extends ServerCall { stream.flush(); } } catch (RuntimeException e) { - close(Status.fromThrowable(e), new Metadata()); + handleInternalError(e); } catch (Error e) { close( Status.CANCELLED.withDescription("Server sendMessage() failed with Error"), @@ -214,7 +215,7 @@ final class ServerCallImpl extends ServerCall { closeCalled = true; if (status.isOk() && method.getType().serverSendsOneMessage() && !messageSent) { - internalClose(Status.INTERNAL.withDescription(MISSING_RESPONSE)); + handleInternalError(Status.INTERNAL.withDescription(MISSING_RESPONSE).asRuntimeException()); return; } @@ -263,10 +264,14 @@ final class ServerCallImpl extends ServerCall { * run until completion, but silently ignore interactions with the {@link ServerStream} from now * on. */ - private void internalClose(Status internalError) { - log.log(Level.WARNING, "Cancelling the stream with status {0}", new Object[] {internalError}); - stream.cancel(internalError); - serverCallTracer.reportCallEnded(internalError.isOk()); // error so always false + private void handleInternalError(Throwable internalError) { + log.log(Level.WARNING, "Cancelling the stream because of internal error", internalError); + Status status = (internalError instanceof StatusRuntimeException) + ? ((StatusRuntimeException) internalError).getStatus() + : Status.INTERNAL.withCause(internalError) + .withDescription("Internal error so cancelling stream."); + stream.cancel(status); + serverCallTracer.reportCallEnded(false); // error so always false } /** diff --git a/core/src/test/java/io/grpc/internal/ServerCallImplTest.java b/core/src/test/java/io/grpc/internal/ServerCallImplTest.java index 10eb7f1504..cef21f6b7f 100644 --- a/core/src/test/java/io/grpc/internal/ServerCallImplTest.java +++ b/core/src/test/java/io/grpc/internal/ServerCallImplTest.java @@ -47,7 +47,6 @@ import io.grpc.SecurityLevel; import io.grpc.ServerCall; import io.grpc.Status; import io.grpc.internal.ServerCallImpl.ServerStreamListenerImpl; -import io.grpc.internal.SingleMessageProducer; import io.perfmark.PerfMark; import java.io.ByteArrayInputStream; import java.io.InputStream; @@ -220,7 +219,7 @@ public class ServerCallImplTest { call.sendMessage(1234L); - verify(stream).close(isA(Status.class), isA(Metadata.class)); + verify(stream).cancel(isA(Status.class)); } @Test