4 回答

TA貢獻1886條經驗 獲得超2個贊
gRPC 不鼓勵您拋出異常以將該錯誤傳達給用戶。這是因為意外泄露您可能沒有考慮發送給客戶的信息是微不足道的。
相反,我們鼓勵您將StatusException
or傳遞StatusRuntimeException
給streamObserver.onError(Throwable)
. 如果您使用異常在您自己的代碼中傳達此信息,您可以在您的代碼中放置一個 try-catch 并將異常傳遞給onError()
. 例如,這對于 可能是公平的StatusException
,因為它是一個已檢查的異常。
有TransmitStatusRuntimeExceptionInterceptor將在回調期間捕獲異常,如果它是StatusRuntimeException
,則關閉異常狀態的調用。這與您的要求非常匹配,但默認情況下并未故意啟用。

TA貢獻1860條經驗 獲得超8個贊
我剛剛發表了一篇關于gRPC Java 中的異常處理和錯誤傳播主題的文章。
您可以使用攔截器處理異常,例如:
public class ExceptionHandler implements ServerInterceptor {
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall, Metadata metadata,
ServerCallHandler<ReqT, RespT> serverCallHandler) {
ServerCall.Listener<ReqT> listener = serverCallHandler.startCall(serverCall, metadata);
return new ExceptionHandlingServerCallListener<>(listener, serverCall, metadata);
}
private class ExceptionHandlingServerCallListener<ReqT, RespT>
extends ForwardingServerCallListener.SimpleForwardingServerCallListener<ReqT> {
private ServerCall<ReqT, RespT> serverCall;
private Metadata metadata;
ExceptionHandlingServerCallListener(ServerCall.Listener<ReqT> listener, ServerCall<ReqT, RespT> serverCall,
Metadata metadata) {
super(listener);
this.serverCall = serverCall;
this.metadata = metadata;
}
@Override
public void onHalfClose() {
try {
super.onHalfClose();
} catch (RuntimeException ex) {
handleException(ex, serverCall, metadata);
throw ex;
}
}
@Override
public void onReady() {
try {
super.onReady();
} catch (RuntimeException ex) {
handleException(ex, serverCall, metadata);
throw ex;
}
}
private void handleException(RuntimeException exception, ServerCall<ReqT, RespT> serverCall, Metadata metadata) {
if (exception instanceof IllegalArgumentException) {
serverCall.close(Status.INVALID_ARGUMENT.withDescription(exception.getMessage()), metadata);
} else {
serverCall.close(Status.UNKNOWN, metadata);
}
}
}
}

TA貢獻1946條經驗 獲得超4個贊
gRPC 不會傳播錯誤。來自官方文檔-
使用給定原因創建 Status 的派生實例。但是,原因不會從服務器傳輸到客戶端。
如果您想將自定義信息從服務器傳遞到客戶端,那么您有幾個選擇 -
使用元數據將錯誤信息從服務器傳播到客戶端
用于
google.rpc.Status
傳遞錯誤詳細信息repeated google.protobuf.Any details
您需要在這兩種情況下捕獲異常,準備一條錯誤消息,并將其發送回客戶端。
我寫了一篇關于gRPC 錯誤處理的詳細博客文章。
添加回答
舉報