[P1] Converge two RetrievalTest handler implementations and unify error code convention

这是一条内部重构类(refactor)Issue,不是用户侧运行报错。它的核心是 RAGFlow 的 Go 层检索测试接口 [P1] Converge two RetrievalTest handler implementations and unify error code convention—

快速结论:这是一条内部重构类(refactor)Issue,不是用户侧运行报错。它的核心是 RAGFlow 的 Go 层检索测试接口 [P1] Converge two RetrievalTest handler implementations and unify error code convention——同一个 service.ChunkService.RetrievalTest() 被两个 handler 以不同方式调用,导致错误码、响应结构和安全策略不一致。如果你是在排查 /datasets/search 或 /searchbots/retrieval_test 的返回码混乱,优先确认请求命中的是哪个 handler。

适用环境:Issue 中仅确认涉及 RAGFlow 的 Go 后端 handler 代码(internal/handler/chunk.go、internal/common/error_code.go)及相关分支 feat/searchbots-retrieval-test。未提及操作系统、Python、CUDA、显卡或具体依赖版本。

最快修复方案:暂无确认的一步修复方案。Issue 中提出的解决方向是抽取 service.CallRetrievalTest() 共享包装、统一错误码约定并加 lint 规则,但截至 Issue 关闭时评论只确认了当前代码现状,未记录已合并的验证结果。

注意事项:两个 handler 保留独立 DTO 是刻意设计(dataset_ids 与 kb_id 的 JSON tag 差异用于兼容 Python API),合并不应动 DTO 层。此外错误码统一属于跨全代码库的约定,改动会同时影响前端和 SDK 的错误处理路径,需评估兼容性。

问题场景

在 RAGFlow 的 Go 后端中,两个 handler 端点调用同一个检索测试业务逻辑 service.ChunkService.RetrievalTest():

  • chunkHandler,路由 /datasets/search
  • searchBotHandler,路由 /searchbots/retrieval_test

这两条路径在请求 DTO、JSON tag、kb_id 类型、鉴权失败处理、参数校验错误码、服务端错误信息暴露程度、默认值填充方式和响应结构上几乎全面分叉。结果就是同一个业务操作对外呈现两套 API 契约,前端/SDK 需要维护两条错误处理路径,且其中一个端点泄漏内部错误细节,另一个则做了保护。

该问题是在对 feat/searchbots-retrieval-test 分支的 CTO 级代码评审中发现的,与 P0 级别的 #15743(系统性的 err.Error() 泄漏)相关联。

报错原文

本 Issue 属于重构讨论,没有典型运行时堆栈,核心问题标识为:

[P1] Converge two RetrievalTest handler implementations and unify error code convention

Validation errors  -> Hardcoded `400`
Service errors     -> `err.Error()` leaked
Error code confusion -> `101` vs `400` for the same class of error

评论中补充确认的当前代码不一致点:

Auth errors       -> jsonError() (HTTP 200 with error code in body)
Validation errors -> c.JSON(http.StatusBadRequest, ...) with hardcoded `400`
Service errors    -> c.JSON(http.StatusInternalServerError, ...) with `err.Error()` leaked

原因分析

可能原因是错误码约定在代码库中从未被统一,导致不同时期编写的 handler 各自采用了一套风格:

  • 部分 handler 使用 common.CodeArgumentError(值为 101);
  • 部分 handler 直接硬编码 400;
  • 部分使用 jsonError(),即返回 HTTP 200 但把错误码放在响应体里;
  • 还有部分直接调用 c.JSON(400/500)。

评论指出,common 包其实已经定义了 CodeBadRequest(400)、CodeServerError(500)、CodeArgumentError(101) 等常量,但 ChunkHandler 仍在使用硬编码数字字面量,说明常量存在但未被一致采用。

从代码库整体趋势看,较新的 handler(MCP、Datasets、Connector)已经收敛到「始终使用 jsonError(),HTTP 200 + 响应体中的 code 字段区分错误」这一模式,而较老的 handler 仍在使用 HTTP 状态码。这就是新旧两套风格并存、且改进只能单向流动(修了一个 handler,另一个不受益)的根本原因。

环境排查

  • 确认当前检出的 RAGFlow 版本/分支,是否包含 searchBotHandler(评论指出该 handler 在 b0a45809 提交时可能尚未合并,仍在 feat/searchbots-retrieval-test 分支上)。
  • 确认请求实际命中的路由:/datasets/search 对应 chunkHandler,/searchbots/retrieval_test 对应 searchBotHandler。
  • 检查 internal/handler/chunk.go 中 RetrievalTest 的鉴权、校验、服务错误三个分支各自使用的返回方式。
  • 检查 internal/common/error_code.go 中已定义的错误码常量,确认调用方是否在用字面量替代常量。
  • 确认前端/SDK 侧是否同时兼容 HTTP 200 + body code 与真实 HTTP 4xx/5xx 两种错误语义。
  • 本 Issue 未涉及 Python、CUDA、PyTorch、显卡或节点依赖版本,无需排查这些项。

解决步骤

  1. 抽取共享调用包装:新增 service.CallRetrievalTest(req, userID),把 Warn 级别日志与通用错误信息封装进去,替代当前直接泄漏 err.Error() 的写法。
  2. 让两个 handler 都改为调用该共享包装,消除「同一业务、两套错误处理」的分叉。
  3. 保留两个 handler 各自的 DTO,不要合并。dataset_ids 与 kb_id 的 JSON tag 差异是按 Python API 兼容性刻意保留的。
  4. 将 chunkHandler 中硬编码的 400 统一替换为 common.CodeArgumentError,服务端错误使用 common.CodeServerError。
  5. 把错误码约定(倾向采用较新 handler 已收敛的 jsonError() → HTTP 200 + body code 模式)写成文档,供所有 Go handler 遵循。
  6. 增加 lint 规则,检测 handler 中直接出现的 c.JSON(http.StatusBadRequest, ...) / c.JSON(http.StatusInternalServerError, ...),提示改用 jsonError,防止回归。
  7. 待 searchBotHandler 分支合并后,按 Issue 正文中的对比表逐项逐维度收敛差异。

验证方法

Issue 中未记录明确的验证结果,可参考以下方向自行确认:

  • 对同类型错误(如参数校验失败)分别请求 /datasets/search 与 /searchbots/retrieval_test,确认返回的 code 字段一致,不再出现 101 与 400 混用。
  • 触发一次服务端错误,确认响应体中不再包含内部 err.Error() 细节,而是通用提示信息。
  • 确认两个端点的成功响应结构与错误响应结构形状一致(例如是否都包含 "data" 字段)。
  • 运行新增的 lint 规则,确认代码库中不再有新增的裸 c.JSON(4xx/5xx) 调用。

参考来源

infiniflow/ragflow #15744

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 26314

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注