亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Spring Boot gRPC:發生業務錯誤時如何返回錯誤碼?

Spring Boot gRPC:發生業務錯誤時如何返回錯誤碼?

楊__羊羊 2023-03-09 15:31:39
我正在使用LogNet grpc-spring-boot-starter實現 gRPC API 。例如,INVALID_ARGUMENT當傳遞了不正確的參數時,我想返回一個錯誤代碼。如果我拋出自定義異常,它會以io.grpc.StatusRuntimeException: UNKNOWN.問:是否可以定義一些異常處理機制,使特定類型的異常始終導致正確的 gRPC 狀態?不幸的是,項目中沒有那么多文檔。
查看完整描述

4 回答

?
MM們

TA貢獻1886條經驗 獲得超2個贊

gRPC 不鼓勵您拋出異常以將該錯誤傳達給用戶。這是因為意外泄露您可能沒有考慮發送給客戶的信息是微不足道的。

相反,我們鼓勵您將StatusExceptionor傳遞StatusRuntimeExceptionstreamObserver.onError(Throwable). 如果您使用異常在您自己的代碼中傳達此信息,您可以在您的代碼中放置一個 try-catch 并將異常傳遞給onError(). 例如,這對于 可能是公平的StatusException,因為它是一個已檢查的異常。

TransmitStatusRuntimeExceptionInterceptor將在回調期間捕獲異常,如果它是StatusRuntimeException,則關閉異常狀態的調用。這與您的要求非常匹配,但默認情況下并未故意啟用。


查看完整回答
反對 回復 2023-03-09
?
桃花長相依

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);

            }

        }

    }

}


查看完整回答
反對 回復 2023-03-09
?
絕地無雙

TA貢獻1946條經驗 獲得超4個贊

gRPC 不會傳播錯誤。來自官方文檔-

使用給定原因創建 Status 的派生實例。但是,原因不會從服務器傳輸到客戶端。

如果您想將自定義信息從服務器傳遞到客戶端,那么您有幾個選擇 -

  1. 使用元數據將錯誤信息從服務器傳播到客戶端

  2. 用于google.rpc.Status傳遞錯誤詳細信息repeated google.protobuf.Any details

您需要在這兩種情況下捕獲異常,準備一條錯誤消息,并將其發送回客戶端。

我寫了一篇關于gRPC 錯誤處理的詳細博客文章。


查看完整回答
反對 回復 2023-03-09
?
江戶川亂折騰

TA貢獻1851條經驗 獲得超5個贊

啟動器的最新版本集成了 spring 驗證支持。如果驗證失敗,它返回 INVALID_ARGUMENT。

披露:我是這個啟動器的創建者。


查看完整回答
反對 回復 2023-03-09
  • 4 回答
  • 0 關注
  • 349 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號