Version: 0.9.78.dev.260506

This commit is contained in:
Losita
2026-05-06 00:30:08 +08:00
parent 3b6fca44a6
commit 33227e48a7
71 changed files with 13137 additions and 62 deletions

View File

@@ -0,0 +1,94 @@
package taskclassforum
import (
"errors"
"fmt"
"strings"
"github.com/LoveLosita/smartflow/backend/shared/respond"
"google.golang.org/genproto/googleapis/rpc/errdetails"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
// responseFromRPCError 把计划广场 zrpc 错误恢复成 HTTP 层可处理的业务错误。
//
// 职责边界:
// 1. 优先读取 taskclassforum RPC 写入的 ErrorInfo恢复 respond.Response
// 2. 对网络、超时、服务不可用等非业务错误保留为普通 error让 HTTP 层按 500 处理;
// 3. 暂不复用 userauth/errors.go因为 user/auth 还承担历史 legacy code 兼容,计划广场只消费新 ErrorInfo 协议。
func responseFromRPCError(err error) error {
if err == nil {
return nil
}
st, ok := status.FromError(err)
if !ok {
return wrapRPCError(err)
}
if resp, ok := responseFromStatusDetails(st); ok {
return resp
}
switch st.Code() {
case codes.Internal, codes.Unknown, codes.Unavailable, codes.DeadlineExceeded, codes.DataLoss, codes.Unimplemented:
msg := strings.TrimSpace(st.Message())
if msg == "" {
msg = "taskclassforum zrpc service internal error"
}
return wrapRPCError(errors.New(msg))
case codes.NotFound:
return responseWithFallback(st, respond.UserTaskClassNotFound)
case codes.PermissionDenied, codes.Unauthenticated:
return responseWithFallback(st, respond.ErrUnauthorized)
case codes.InvalidArgument:
return responseWithFallback(st, respond.MissingParam)
}
msg := strings.TrimSpace(st.Message())
if msg == "" {
msg = "taskclassforum zrpc service rejected request"
}
return respond.Response{Status: "400", Info: msg}
}
func responseFromStatusDetails(st *status.Status) (respond.Response, bool) {
if st == nil {
return respond.Response{}, false
}
for _, detail := range st.Details() {
info, ok := detail.(*errdetails.ErrorInfo)
if !ok {
continue
}
statusValue := strings.TrimSpace(info.Reason)
if statusValue == "" {
return respond.Response{}, false
}
message := strings.TrimSpace(st.Message())
if message == "" && info.Metadata != nil {
message = strings.TrimSpace(info.Metadata["info"])
}
if message == "" {
message = statusValue
}
return respond.Response{Status: statusValue, Info: message}, true
}
return respond.Response{}, false
}
func responseWithFallback(st *status.Status, fallback respond.Response) respond.Response {
msg := strings.TrimSpace(st.Message())
if msg == "" {
msg = fallback.Info
}
return respond.Response{Status: fallback.Status, Info: msg}
}
func wrapRPCError(err error) error {
if err == nil {
return nil
}
return fmt.Errorf("调用 taskclassforum zrpc 服务失败: %w", err)
}