4 回答

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

TA貢獻(xiàn)1860條經(jīng)驗 獲得超8個贊
我剛剛發(fā)表了一篇關(guān)于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貢獻(xiàn)1946條經(jīng)驗 獲得超4個贊
gRPC 不會傳播錯誤。來自官方文檔-
使用給定原因創(chuàng)建 Status 的派生實例。但是,原因不會從服務(wù)器傳輸?shù)娇蛻舳恕?/em>
如果您想將自定義信息從服務(wù)器傳遞到客戶端,那么您有幾個選擇 -
使用元數(shù)據(jù)將錯誤信息從服務(wù)器傳播到客戶端
用于
google.rpc.Status
傳遞錯誤詳細(xì)信息repeated google.protobuf.Any details
您需要在這兩種情況下捕獲異常,準(zhǔn)備一條錯誤消息,并將其發(fā)送回客戶端。
我寫了一篇關(guān)于gRPC 錯誤處理的詳細(xì)博客文章。

TA貢獻(xiàn)1851條經(jīng)驗 獲得超5個贊
啟動器的最新版本集成了 spring 驗證支持。如果驗證失敗,它返回 INVALID_ARGUMENT。
披露:我是這個啟動器的創(chuàng)建者。
添加回答
舉報