Closed CrazyZfp closed 7 years ago
As mentioned in the Status Javadoc:
Create a derived instance of {@link Status} with the given cause. However, the cause is not transmitted from server to client.
If you want to propagate the exception across the wire, you'll need to make your own custom header.
@carl-mastrangelo I am facing the same issue using scalapb.
override def healthCheck(request: HealthCheckRequest, streamObserver: StreamObserver[HealthCheckResponse]) = {
log.info("Health check endpoint")
// streamObserver.onNext(HealthCheckResponse(status = "UP"))
// streamObserver.onCompleted()
try {
throw new CustomException("Custom exception!")
}
catch {
case e: CustomException => {
streamObserver.onError(Status.INTERNAL.withDescription(e.getMessage).augmentDescription("customException()").withCause(CustomException(e.getMessage)).asRuntimeException)
}
}
}
status.getCode() and status.getDescription() can get the correct value , but status.getCause() is always null.
Could you please provide the steps to create headers and pass the exception object back to client?
@vegoutha
Here is a sample interceptor for putting it in. You can write a similar one for pulling it out.
private static class ExceptionInterceptor implements ClientInterceptor {
private static final Metadata.Key<byte[]> exceptionKey =
Metadata.Key.of("my-metadata", Metadata.BINARY_BYTE_MARSHALLER);
@Override
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method,
CallOptions callOptions, Channel next) {
final ClientCall<ReqT, RespT> call = next.newCall(method, callOptions);
return new SimpleForwardingClientCall<ReqT, RespT>(call) {
@Override
public void start(Listener<RespT> responseListener, Metadata headers) {
super.start(new SimpleForwardingClientCallListener<RespT>(responseListener) {
@Override
public void onClose(Status status, Metadata trailers) {
if (status.getCause() != null) {
trailers.put(
exceptionKey, status.getCause().toString().getBytes(StandardCharsets.UTF_8));
}
super.onClose(status, trailers);
}
}, headers);
}
};
}
}
Please answer these questions before submitting your issue.
What version of gRPC are you using?
1.3.0
What JVM are you using (
java -version
)?java version "1.8.0_51" Java(TM) SE Runtime Environment (build 1.8.0_51-b16) Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)
What did you do?
In server interceptor, I close ServerCall and set a Status with Throwable instance:
In client, I use
Status status = Status.fromThrowable(e);
to get the Status returned from server.status.getCode()
andstatus.getDescription()
can get the correct value , butstatus.getCause()
is alwaysnull
.What did you expect to see?
In client, I can get the correct Throwable instance rather than
null
bystatus.getCause()
What did you see instead?
staus.getCause()
is alwaysnull