observer.onError(new IllegalStateException("my message")); } catch (Exception e) {
response.onError(new StatusException(Status.INTERNAL.withDescription(e.getMessage()).withCause(e)));
}Having a StreamObserver in the server, if we do:observer.onError(new IllegalStateException("my message"));we get in the client a StatusRuntimeException with message "UNKNOWN" and code also set to UNKNOWN.
I think would be useful to send back at least the message of the exception. The problem is that unless we pass a StatusException or StatusRuntimeException, the message is lost.
Right now, I achieve that with this workaround:} catch (Exception e) {
response.onError(new StatusException(Status.INTERNAL.withDescription(e.getMessage()).withCause(e)));
}
public void close(Status status, String message) {
You can create a ServerInterceptor that can copy any cause message to the status.public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(MethodDescriptor<ReqT, RespT> method,ServerCall<RespT> call,Metadata headers,ServerCallHandler<ReqT, RespT> next) {return new SimpleForwardingServerCall(next.startCall(method, call, headers)) {@Overridepublic void close(Status status, String message) {if (status.getDescription() == null&& status.getCause() != null) {status = status.withDescription(status.getCause().getMessage());}super.close(status, message):}};}
private ServerInterceptor serverInterceptor = new ServerInterceptor() {
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
ServerCall<ReqT, RespT> serverCall,
Metadata metadata,
ServerCallHandler<ReqT, RespT> next) {
logger.info("intercept {}" , serverCall.getMethodDescriptor().getFullMethodName());
// how to replace the following line ?
return next.startCall(serverCall, metadata);
}
};responseObserver.onError(new StatusRuntimeException(Status.INTERNAL.withDescription(e.getMessage())));
so that in the server code, we don't need to try catch RuntimeException , and write the above code in each method call.