package wrapper import ( "context" "encoding/json" "git.hlsq.asia/alex/service-common/net/http/httpresp" "git.hlsq.asia/alex/service-common/proto/rs/rscommon" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "net/http" ) // ErrorHandler 将 gRPC 错误转为统一 JSON 格式 func ErrorHandler(_ context.Context, _ *runtime.ServeMux, _ runtime.Marshaler, w http.ResponseWriter, _ *http.Request, err error) { st, ok := status.FromError(err) if !ok { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) _ = json.NewEncoder(w).Encode(httpresp.Error(httpresp.Failed)) return } code, msg := 0, "" for _, detail := range st.Details() { if errorInfo, ok := detail.(*rscommon.ErrorInfo); ok { code = int(errorInfo.Code) msg = errorInfo.Msg break } } if code == 0 { code = httpresp.Failed.Code() msg = httpresp.Failed.Error() } if st.Code() == codes.Unknown || st.Code() == codes.Unimplemented || st.Code() == codes.NotFound { msg = st.Message() } if st.Code() == codes.NotFound { code = httpresp.NotFound.Code() } w.Header().Set("Content-Type", "application/json") w.WriteHeader(grpcCodeToHTTPCode(st.Code())) _ = json.NewEncoder(w).Encode(httpresp.Error(httpresp.NewCode(code, msg))) } // 这里定义 Internal 属于业务错误,其他的属于 500 报错 func grpcCodeToHTTPCode(c codes.Code) int { switch c { case codes.OK, codes.Unknown: return http.StatusOK case codes.Unimplemented, codes.NotFound: return http.StatusNotFound default: return http.StatusInternalServerError } }