apache/shenyu · error · ShenyuGrpcException
Caught exception while waiting for rpc
Error message
Caught exception while waiting for rpc :{ ${e.getMessage()}} What it means
ShenyuGrpcClient.call waits on a Future for the gRPC response. An InterruptedException is handled by re-interrupting the thread and throwing ShenyuGrpcException('Caught exception while waiting for rpc ...') wrapping the cause, so callers get a consistent gateway exception when the blocking wait fails.
Solutions
- Read the wrapped cause (e.getCause()) to find the real gRPC failure (deadline exceeded, UNAVAILABLE, etc.).
- Check gRPC server health/connectivity if the cause is a transport error (UNAVAILABLE, connection refused).
- Increase the gRPC deadline/timeout config if long-running calls are being cancelled.
- Avoid shutting down or undeploying the gateway while calls are in flight; drain traffic first.
Defensive patterns
Strategy: try-catch
Try / catch
try {
return shenyuGrpcClient.call(request);
} catch (ShenyuGrpcException e) {
Throwable root = e.getCause();
LOG.error("grpc rpc wait failed, root cause: {}", root == null ? e : root.getMessage());
return errorResponse(exchange, HttpStatus.GATEWAY_TIMEOUT);
} Prevention
- Set sane gRPC deadlines so hung calls fail fast instead of being interrupted by cancellation.
- Monitor gateway shutdowns/cancellations during in-flight rpc calls.
- Log and alert on e.getCause() to distinguish interruption vs. upstream failure.
- Ensure health checks keep upstream gRPC servers reachable.
When it happens
Trigger: The thread blocked on future.get() inside call() is interrupted — typically by gateway timeout/dispatcher cancellation or shutdown — or an ExecutionException occurs because the underlying gRPC invocation failed.
Common situations: Client disconnects or request times out and the reactive pipeline cancels the work; gateway shutdown while gRPC calls are in flight; upstream gRPC server error surfacing via ExecutionException.
Related errors
- apollo client getItemValue time out
- grpc client must config the contextPath, ipAndPort
- build json response message is error, newBuilder method is…
- can not get defaultInstance Field of
- can not get fullMethodName Field of
AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12).
Data as JSON: /api/errors/8438f5689a10ba13.
Report an issue: GitHub.
Appendix: source
Thrown at shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-rpc/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/client/ShenyuGrpcClient.java:104
ShenyuGrpcCallRequest callParams = new ShenyuGrpcCallRequest();
callParams.setMethodDescriptor(jsonMarshallerMethodDescriptor);
callParams.setChannel(channel);
callParams.setCallOptions(callOptions);
callParams.setResponseObserver(streamObserver);
callParams.setRequests(jsonRequestList);
try {
this.invoke(callParams).get();
} catch (InterruptedException e) {
// InterruptedExceptions should never be ignored in the code.
// InterruptedExceptions should either be rethrown - immediately or after cleaning up the method’s state -
// or the thread should be re-interrupted by calling Thread.interrupt() even if this is supposed to be a single-threaded application.
// Any other course of action risks delaying thread shutdown and loses the information
// that the thread was interrupted - probably without finishing its task.
LOG.error("Grpc plugin invoke method is exception, Will cause the thread to be interrupted");
Thread.currentThread().interrupt();
throw new ShenyuGrpcException("Caught exception while waiting for rpc :{ " + e.getMessage() + "}", e);
} catch (ExecutionException e) {
throw new ShenyuGrpcException("Caught exception while waiting for rpc :{ " + e.getMessage() + "}", e);
}
return CompletableFuture.completedFuture(shenyuGrpcResponse);
}
/**
* Grpc call.
*
* @param callParams callParams
* @return ListenableFuture future
*/
public ListenableFuture<Void> invoke(final ShenyuGrpcCallRequest callParams) {
MethodDescriptor.MethodType methodType = callParams.getMethodDescriptor().getType();
List<DynamicMessage> requestList = callParams.getRequests();
StreamObserver<DynamicMessage> responseObserver = callParams.getResponseObserver();
CompleteObserver<DynamicMessage> doneObserver = new CompleteObserver<>();View on GitHub (pinned to 567142e072)