fix: 1.调整公共code输出方法 2.调整商品抓取工作流日志及错误输出

This commit is contained in:
fuzhongyun 2025-12-22 14:08:48 +08:00
parent b87767ea5a
commit c1b7cd6bf5
14 changed files with 62 additions and 66 deletions

View File

@ -349,7 +349,7 @@ func (d *Do) LoadUserPermission(client *gateway.Client, requireData *entitys.Req
// 检查响应状态码 // 检查响应状态码
if res.StatusCode != http.StatusOK { if res.StatusCode != http.StatusOK {
err = errors.SysErr("获取用户权限失败") err = errors.SysErrf("获取用户权限失败")
return return
} }

View File

@ -74,7 +74,7 @@ func (r *Handle) Recognize(ctx context.Context, rec *entitys.Recognize, promptPr
entitys.ResLog(rec.Ch, "recognize_end", "意图识别结束") entitys.ResLog(rec.Ch, "recognize_end", "意图识别结束")
var match entitys.Match var match entitys.Match
if err = json.Unmarshal([]byte(recognizeMsg), &match); err != nil { if err = json.Unmarshal([]byte(recognizeMsg), &match); err != nil {
err = errors.SysErr("数据结构错误:%v", err.Error()) err = errors.SysErrf("数据结构错误:%v", err.Error())
return return
} }
rec.Match = &match rec.Match = &match

View File

@ -70,13 +70,13 @@ func (t *TaskBiz) GetUserPermission(req *entitys.TaskRequest, auth string) (code
// 发送请求 // 发送请求
res, err := request.Send() res, err := request.Send()
if err != nil { if err != nil {
err = errors.SysErr("请求用户权限失败") err = errors.SysErrf("请求用户权限失败")
return return
} }
// 检查响应状态码 // 检查响应状态码
if res.StatusCode != http.StatusOK { if res.StatusCode != http.StatusOK {
err = errors.SysErr("获取用户权限失败") err = errors.SysErrf("获取用户权限失败")
return return
} }

View File

@ -44,22 +44,26 @@ func NewBusinessErr(code int, message string) *BusinessErr {
return &BusinessErr{code: code, message: message} return &BusinessErr{code: code, message: message}
} }
func SysErr(message string, arg ...any) *BusinessErr { func SysErrf(message string, arg ...any) *BusinessErr {
return &BusinessErr{code: SystemError.code, message: fmt.Sprintf(message, arg)} return &BusinessErr{code: SystemError.code, message: fmt.Sprintf(message, arg)}
} }
func ParamErr(message string, arg ...any) *BusinessErr { func SysErr(message string) *BusinessErr {
return &BusinessErr{code: SystemError.code, message: message}
}
func ParamErrf(message string, arg ...any) *BusinessErr {
return &BusinessErr{code: ParamError.code, message: fmt.Sprintf(message, arg)} return &BusinessErr{code: ParamError.code, message: fmt.Sprintf(message, arg)}
} }
func ParamErr(message string) *BusinessErr {
return &BusinessErr{code: ParamError.code, message: message}
}
func (e *BusinessErr) Wrap(err error) *BusinessErr { func (e *BusinessErr) Wrap(err error) *BusinessErr {
return NewBusinessErr(e.code, err.Error()) return NewBusinessErr(e.code, err.Error())
} }
func KeyErr() *BusinessErr {
return &BusinessErr{code: KeyNotFound.code, message: KeyNotFound.message}
}
func WorkflowErr(message string) *BusinessErr { func WorkflowErr(message string) *BusinessErr {
return NewBusinessErr(WorkflowError.code, message) return NewBusinessErr(WorkflowError.code, message)
} }

View File

@ -7,6 +7,7 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
) )
type Client struct { type Client struct {
@ -22,8 +23,7 @@ func New(cfg config.ToolConfig) *Client {
func (c *Client) Call(ctx context.Context, toolReq *ProductUploadRequest) (toolResp *ProductUploadResponse, err error) { func (c *Client) Call(ctx context.Context, toolReq *ProductUploadRequest) (toolResp *ProductUploadResponse, err error) {
// 商品有且只能有一个 // 商品有且只能有一个
if len(toolReq.GoodsList) != 1 { if len(toolReq.GoodsList) != 1 {
err = errors.New("商品只能有一个") return nil, errors.New("商品只能有一个")
return
} }
apiReq, _ := util.StructToMap(toolReq) apiReq, _ := util.StructToMap(toolReq)
@ -36,7 +36,7 @@ func (c *Client) Call(ctx context.Context, toolReq *ProductUploadRequest) (toolR
res, err := req.Send() res, err := req.Send()
if err != nil { if err != nil {
return return nil, fmt.Errorf("请求失败err: %v", err)
} }
type resType struct { type resType struct {
@ -49,15 +49,13 @@ func (c *Client) Call(ctx context.Context, toolReq *ProductUploadRequest) (toolR
var resMap resType var resMap resType
err = json.Unmarshal([]byte(res.Text), &resMap) err = json.Unmarshal([]byte(res.Text), &resMap)
if err != nil { if err != nil {
return return nil, fmt.Errorf("解析响应失败err: %v", err)
} }
if resMap.Code != 200 { if resMap.Code != 200 {
err = errors.New("货易通商品创建失败") return nil, fmt.Errorf("业务错误code: %d, msg: %s", resMap.Code, resMap.Msg)
return
} }
if len(resMap.Data.Ids) == 0 { if len(resMap.Data.Ids) == 0 {
err = errors.New("货易通商品创建失败") return nil, fmt.Errorf("ids为空")
return
} }
toolResp = &ProductUploadResponse{ toolResp = &ProductUploadResponse{

View File

@ -48,24 +48,20 @@ func (c *Client) Call(ctx context.Context, name string) (int, error) {
res, err := req.Send() res, err := req.Send()
if err != nil { if err != nil {
return 0, err return 0, fmt.Errorf("请求失败err: %v", err)
}
if res.StatusCode != 200 {
return 0, fmt.Errorf("supplier search failed with status code: %d", res.StatusCode)
} }
var resData SearchResponse var resData SearchResponse
if err := json.Unmarshal([]byte(res.Text), &resData); err != nil { if err := json.Unmarshal([]byte(res.Text), &resData); err != nil {
return 0, fmt.Errorf("failed to parse supplier search response: %w", err) return 0, fmt.Errorf("解析响应失败err: %v", err)
} }
if resData.Code != 200 { if resData.Code != 200 {
return 0, fmt.Errorf("supplier search business error: %s", resData.Msg) return 0, fmt.Errorf("业务错误code: %d, msg: %s", resData.Code, resData.Msg)
} }
if len(resData.Data.List) == 0 { if len(resData.Data.List) == 0 {
return 0, fmt.Errorf("supplier not found: %s", name) return 0, fmt.Errorf("供应商不存在")
} }
return resData.Data.List[0].ID, nil return resData.Data.List[0].ID, nil

View File

@ -43,24 +43,20 @@ func (c *Client) Call(ctx context.Context, name string) (int, error) {
res, err := req.Send() res, err := req.Send()
if err != nil { if err != nil {
return 0, err return 0, fmt.Errorf("请求失败err: %v", err)
}
if res.StatusCode != 200 {
return 0, fmt.Errorf("warehouse search failed with status code: %d", res.StatusCode)
} }
var resData SearchResponse var resData SearchResponse
if err := json.Unmarshal([]byte(res.Text), &resData); err != nil { if err := json.Unmarshal([]byte(res.Text), &resData); err != nil {
return 0, fmt.Errorf("failed to parse warehouse search response: %w", err) return 0, fmt.Errorf("解析响应失败err: %v", err)
} }
if resData.Code != 200 { if resData.Code != 200 {
return 0, fmt.Errorf("warehouse search business error: %s", resData.Msg) return 0, fmt.Errorf("业务错误code: %d, msg: %s", resData.Code, resData.Msg)
} }
if len(resData.Data.List) == 0 { if len(resData.Data.List) == 0 {
return 0, fmt.Errorf("warehouse not found: %s", name) return 0, fmt.Errorf("仓库不存在: %s", name)
} }
return resData.Data.List[0].ID, nil return resData.Data.List[0].ID, nil

View File

@ -11,6 +11,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"log"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -210,7 +211,7 @@ func (o *productUpload) buildWorkflow(ctx context.Context) (compose.Runnable[*Pr
supplierId, err := o.toolManager.Hyt.SupplierSearch.Call(ctx, state.SupplierName) supplierId, err := o.toolManager.Hyt.SupplierSearch.Call(ctx, state.SupplierName)
if err != nil { if err != nil {
// 记录日志,但不阻断流程,可能允许 ID 为 0 // 记录日志,但不阻断流程,可能允许 ID 为 0
fmt.Printf("warning: failed to get supplier id for %s: %v\n", state.SupplierName, err) log.Printf("warning: 供应商ID获取失败%s: %v\n", state.SupplierName, err)
} else { } else {
state.mu.Lock() state.mu.Lock()
defer state.mu.Unlock() defer state.mu.Unlock()
@ -228,7 +229,7 @@ func (o *productUpload) buildWorkflow(ctx context.Context) (compose.Runnable[*Pr
warehouseId, err := o.toolManager.Hyt.WarehouseSearch.Call(ctx, state.WarehouseName) warehouseId, err := o.toolManager.Hyt.WarehouseSearch.Call(ctx, state.WarehouseName)
if err != nil { if err != nil {
fmt.Printf("warning: failed to get warehouse id for %s: %v\n", state.WarehouseName, err) log.Printf("warning: 仓库ID获取失败%s: %v\n", state.WarehouseName, err)
} else { } else {
state.mu.Lock() state.mu.Lock()
defer state.mu.Unlock() defer state.mu.Unlock()
@ -254,7 +255,7 @@ func (o *productUpload) buildWorkflow(ctx context.Context) (compose.Runnable[*Pr
g.AddLambdaNode("upload_product", compose.InvokableLambda(func(ctx context.Context, state *ProductUploadContext) (*ProductUploadContext, error) { g.AddLambdaNode("upload_product", compose.InvokableLambda(func(ctx context.Context, state *ProductUploadContext) (*ProductUploadContext, error) {
toolRes, err := o.toolManager.Hyt.ProductUpload.Call(ctx, state.UploadReq) toolRes, err := o.toolManager.Hyt.ProductUpload.Call(ctx, state.UploadReq)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("商品上传失败")
} }
state.UploadResp = toolRes state.UploadResp = toolRes
return state, nil return state, nil

View File

@ -4,17 +4,18 @@ import (
errors "ai_scheduler/internal/data/error" errors "ai_scheduler/internal/data/error"
"ai_scheduler/internal/data/model" "ai_scheduler/internal/data/model"
"context" "context"
"github.com/google/uuid"
"log" "log"
"math/rand" "math/rand"
"sync" "sync"
"time" "time"
"github.com/google/uuid"
"github.com/gofiber/websocket/v2" "github.com/gofiber/websocket/v2"
) )
var ( var (
ErrConnClosed = errors.SysErr("连接不存在或已关闭") ErrConnClosed = errors.SysErrf("连接不存在或已关闭")
rng = rand.New(rand.NewSource(time.Now().UnixNano())) rng = rand.New(rand.NewSource(time.Now().UnixNano()))
idBuf = make([]byte, 20) idBuf = make([]byte, 20)
) )

View File

@ -54,10 +54,10 @@ func (c *ContactClient) SearchUserOne(accessToken string, name string) (string,
} }
if resp.Body == nil { if resp.Body == nil {
return "", errorcode.ParamErr("empty response body") return "", errorcode.ParamErrf("empty response body")
} }
if len(resp.Body.List) == 0 { if len(resp.Body.List) == 0 {
return "", errorcode.ParamErr("empty user list") return "", errorcode.ParamErrf("empty user list")
} }
userId := resp.Body.List[0] userId := resp.Body.List[0]

View File

@ -67,7 +67,7 @@ func (c *NotableClient) UpdateRecord(accessToken string, req *UpdateRecordReq) (
} }
if resp.Body == nil { if resp.Body == nil {
return false, errorcode.ParamErr("empty response body") return false, errorcode.ParamErrf("empty response body")
} }
return true, nil return true, nil

View File

@ -85,13 +85,13 @@ func (s *CallbackService) Callback(c *fiber.Ctx) error {
// 解析 Envelope // 解析 Envelope
var env Envelope var env Envelope
if err := json.Unmarshal(c.Body(), &env); err != nil { if err := json.Unmarshal(c.Body(), &env); err != nil {
return errorcode.ParamErr("invalid json: %v", err) return errorcode.ParamErrf("invalid json: %v", err)
} }
if env.Action == "" || env.TaskID == "" { if env.Action == "" || env.TaskID == "" {
return errorcode.ParamErr("missing action/task_id") return errorcode.ParamErrf("missing action/task_id")
} }
if env.Data == nil { if env.Data == nil {
return errorcode.ParamErr("missing data") return errorcode.ParamErrf("missing data")
} }
switch sourceKey { switch sourceKey {
@ -141,7 +141,7 @@ func (s *CallbackService) handleDingTalkCallback(c *fiber.Ctx, env Envelope) err
// 校验taskId // 校验taskId
sessionID, ok := s.callBackTool.GetSessionByTaskID(env.TaskID) sessionID, ok := s.callBackTool.GetSessionByTaskID(env.TaskID)
if !ok { if !ok {
return errorcode.ParamErr("missing session_id for task_id: %s", env.TaskID) return errorcode.ParamErrf("missing session_id for task_id: %s", env.TaskID)
} }
ctx := c.Context() ctx := c.Context()
@ -176,14 +176,14 @@ func (s *CallbackService) handleDingTalkCallback(c *fiber.Ctx, env Envelope) err
} }
var data processData var data processData
if err := json.Unmarshal(env.Data, &data); err != nil { if err := json.Unmarshal(env.Data, &data); err != nil {
return errorcode.ParamErr("invalid json: %v", err) return errorcode.ParamErrf("invalid json: %v", err)
} }
s.sendStreamLoading(sessionID, data.Process) s.sendStreamLoading(sessionID, data.Process)
return c.JSON(fiber.Map{"code": 0, "message": "ok"}) return c.JSON(fiber.Map{"code": 0, "message": "ok"})
default: default:
return errorcode.ParamErr("unknown action: %s", env.Action) return errorcode.ParamErrf("unknown action: %s", env.Action)
} }
} }
@ -255,27 +255,27 @@ func (s *CallbackService) sendStreamLoading(sessionID string, content string) {
func (s *CallbackService) handleBugOptimizationSubmitUpdate(ctx context.Context, taskData json.RawMessage) (string, *errorcode.BusinessErr) { func (s *CallbackService) handleBugOptimizationSubmitUpdate(ctx context.Context, taskData json.RawMessage) (string, *errorcode.BusinessErr) {
var data BugOptimizationSubmitUpdateData var data BugOptimizationSubmitUpdateData
if err := json.Unmarshal(taskData, &data); err != nil { if err := json.Unmarshal(taskData, &data); err != nil {
return "", errorcode.ParamErr("invalid data type: %v", err) return "", errorcode.ParamErrf("invalid data type: %v", err)
} }
if data.Creator == "" { if data.Creator == "" {
return "", errorcode.ParamErr("empty creator") return "", errorcode.ParamErrf("empty creator")
} }
// 获取创建者uid // 获取创建者uid
accessToken, _ := s.dingtalkOldClient.GetAccessToken() accessToken, _ := s.dingtalkOldClient.GetAccessToken()
creatorId, err := s.dingtalkContactClient.SearchUserOne(accessToken, data.Creator) creatorId, err := s.dingtalkContactClient.SearchUserOne(accessToken, data.Creator)
if err != nil { if err != nil {
return "", errorcode.ParamErr("invalid data type: %v", err) return "", errorcode.ParamErrf("invalid data type: %v", err)
} }
// 获取用户详情 // 获取用户详情
userDetails, err := s.dingtalkOldClient.QueryUserDetails(ctx, creatorId) userDetails, err := s.dingtalkOldClient.QueryUserDetails(ctx, creatorId)
if err != nil { if err != nil {
return "", errorcode.ParamErr("invalid data type: %v", err) return "", errorcode.ParamErrf("invalid data type: %v", err)
} }
if userDetails == nil { if userDetails == nil {
return "", errorcode.ParamErr("user details not found") return "", errorcode.ParamErrf("user details not found")
} }
unionId := userDetails.UnionID unionId := userDetails.UnionID
@ -288,10 +288,10 @@ func (s *CallbackService) handleBugOptimizationSubmitUpdate(ctx context.Context,
CreatorUnionId: unionId, CreatorUnionId: unionId,
}) })
if err != nil { if err != nil {
return "", errorcode.ParamErr("invalid data type: %v", err) return "", errorcode.ParamErrf("invalid data type: %v", err)
} }
if !ok { if !ok {
return "", errorcode.ParamErr("update record failed") return "", errorcode.ParamErrf("update record failed")
} }
return "问题记录即将完成", nil return "问题记录即将完成", nil
@ -301,16 +301,16 @@ func (s *CallbackService) handleBugOptimizationSubmitUpdate(ctx context.Context,
func (s *CallbackService) handleBugOptimizationSubmitDone(ctx context.Context, taskData json.RawMessage) (string, *errorcode.BusinessErr) { func (s *CallbackService) handleBugOptimizationSubmitDone(ctx context.Context, taskData json.RawMessage) (string, *errorcode.BusinessErr) {
var data BugOptimizationSubmitDoneData var data BugOptimizationSubmitDoneData
if err := json.Unmarshal(taskData, &data); err != nil { if err := json.Unmarshal(taskData, &data); err != nil {
return "", errorcode.ParamErr("invalid data type: %v", err) return "", errorcode.ParamErrf("invalid data type: %v", err)
} }
if len(data.Receivers) == 0 { if len(data.Receivers) == 0 {
return "", errorcode.ParamErr("empty receivers") return "", errorcode.ParamErrf("empty receivers")
} }
// 构建接收者 // 构建接收者
receivers := s.getDingtalkReceivers(ctx, data.Receivers) receivers := s.getDingtalkReceivers(ctx, data.Receivers)
if receivers == "" { if receivers == "" {
return "", errorcode.ParamErr("invalid receivers") return "", errorcode.ParamErrf("invalid receivers")
} }
// 构建跳转链接 // 构建跳转链接

View File

@ -65,11 +65,11 @@ func (s *CapabilityService) ProductIngest(c *fiber.Ctx) error {
// 解析请求参数 // 解析请求参数
req := ProductIngestReq{} req := ProductIngestReq{}
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
return errorcode.ParamErr("invalid request body: %v", err) return errorcode.ParamErrf("invalid request body: %v", err)
} }
// 必要参数校验 // 必要参数校验
if req.Text == "" || req.SysId == "" { if req.Text == "" || req.SysId == "" {
return errorcode.ParamErr("missing required fields") return errorcode.ParamErrf("missing required fields")
} }
// 映射目标系统商品属性中文模板 // 映射目标系统商品属性中文模板
@ -78,7 +78,7 @@ func (s *CapabilityService) ProductIngest(c *fiber.Ctx) error {
case "hyt": // 货易通 case "hyt": // 货易通
sysProductPropertyTemplateZH = constants.HYTProductPropertyTemplateZH sysProductPropertyTemplateZH = constants.HYTProductPropertyTemplateZH
default: default:
return errorcode.ParamErr("invalid sys_id") return errorcode.ParamErrf("invalid sys_id")
} }
// 模型调用 // 模型调用
@ -138,11 +138,11 @@ func (s *CapabilityService) checkRequestHeader(c *fiber.Ctx) error {
// 时间窗口校验 // 时间窗口校验
if ts != "" && !util.IsInTimeWindow(ts, 5*time.Minute) { if ts != "" && !util.IsInTimeWindow(ts, 5*time.Minute) {
// return errorcode.AuthNotFound return errorcode.AuthNotFound
} }
// token校验 // token校验
if token == "" || token != "A7f9KQ3mP2X8LZC4R5e" { if token == "" || token != "A7f9KQ3mP2X8LZC4R5e" {
return errorcode.KeyErr() return errorcode.KeyNotFound
} }
return nil return nil
@ -164,12 +164,12 @@ func (s *CapabilityService) ProductIngestConfirm(c *fiber.Ctx) error {
// 获取路径参数中的 thread_id // 获取路径参数中的 thread_id
threadId := c.Params("thread_id") threadId := c.Params("thread_id")
if threadId == "" { if threadId == "" {
return errorcode.ParamErr("missing required fields") return errorcode.ParamErrf("missing required fields")
} }
// 解析请求参数 body // 解析请求参数 body
req := ProductIngestConfirmReq{} req := ProductIngestConfirmReq{}
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
return errorcode.ParamErr("invalid request body: %v", err) return errorcode.ParamErrf("invalid request body: %v", err)
} }
// 必要参数校验 // 必要参数校验
if req.Confirmed == "" || threadId == "" { if req.Confirmed == "" || threadId == "" {

View File

@ -60,7 +60,7 @@ func (w *CallBackTool) BugOptimizationSubmit(ctx context.Context, requireData *e
cond = cond.And(builder.Eq{"session_id": requireData.Session}) cond = cond.And(builder.Eq{"session_id": requireData.Session})
sessionInfo, err := w.sessionImpl.GetOneBySearch(&cond) sessionInfo, err := w.sessionImpl.GetOneBySearch(&cond)
if err != nil { if err != nil {
err = errors.SysErr("获取会话信息失败:%v", err.Error()) err = errors.SysErrf("获取会话信息失败:%v", err.Error())
return return
} }
userName := sessionInfo["user_name"].(string) userName := sessionInfo["user_name"].(string)