Skip to content

fix(service-datasource,rest): the last three uncovered datasource routes answer their registered refusal code (#4264) - #4313

Merged
os-zhuang merged 1 commit into
mainfrom
claude/datasource-routes-service-throw-eo9izy
Jul 31, 2026
Merged

fix(service-datasource,rest): the last three uncovered datasource routes answer their registered refusal code (#4264)#4313
os-zhuang merged 1 commit into
mainfrom
claude/datasource-routes-service-throw-eo9izy

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Closes #4264(#4249 / #4263 的后续)。

问题

#4263 只覆盖了 issue 点名的两条 introspection 路由;还剩三条兄弟路由的服务调用完全没有 catch,服务一抛,rejection 被适配器吞掉(.catch(() => resolve(null))),客户端拿到的是 pre-#3675 形态的非信封 500 { error: 'No response from handler' } —— 没有 success 标志、body.error.message === undefined、没有可切换的 code,真实原因彻底丢失。

修复

形状与 #4249 完全相同:包住服务调用,回 400 声明信封,error.code 用该路由所派发服务在 ADR-0112 账本中注册的 refusal code,error.message 携带服务自己的消息:

路由 服务调用 现在抛出时
GET /api/v1/datasources listDatasources 400 DATASOURCE_ADMIN_ERROR
POST /api/v1/datasources/:name/external/refresh-catalog refreshCatalog 400 EXTERNAL_DATASOURCE_ERROR
POST /api/v1/datasources/:name/external/validate validateAll 400 EXTERNAL_DATASOURCE_ERROR

裁决:注册 refusal code,而非 INTERNAL_ERROR

Issue 留了一个待裁决点(listDatasources 失败更像后端故障)。本 PR 选注册 code,理由:

  1. 模块内一致性。 两个模块里其余每条 catch 分支 —— 包括纯读路由(getDatasourcelistRemoteTables)—— 都已经以 400 + 服务归属 code 应答。这三条改回 500 会在同一模块内分叉失败契约,正是 The same three datasource-admin routes answer 400 with the wrong service's error code (#4225 follow-up, one field over) #4249 消除的那类漂移("one operation, one failure contract")。
  2. 同类抛出已有裁决先例。 refreshCatalog 的主要抛出类别(未知 datasource、远端不可达、no such schema)与 listRemoteTables 完全同类,The same three datasource-admin routes answer 400 with the wrong service's error code (#4225 follow-up, one field over) #4249 已把后者裁为 400 refusal。
  3. 归属不丢失。 账本把这两个 code 读作"来自 X 服务的 refusal",按 code 切换的客户端保留服务溯源;一刀切 INTERNAL_ERROR 会抹掉这一机器可读归属。

若维护者仍倾向 INTERNAL_ERROR,改动集中在两处 helper,易于翻转。

变更明细

验证

  • service-datasource 全套 10 files / 180 tests 通过;rest 全套 35 files / 523 tests 通过。
  • scripts/check-route-envelope.mjs 通过(该门审计写点,本次只新增经 sendError 的写点)。
  • turbo build(含 dts)通过。

Generated by Claude Code

…tes answer their registered refusal code (#4264)

#4249 (#4263) gave the rest surface's two introspection routes a failure
contract; three sibling routes still had no catch around their service
call, so a throw was swallowed by the adapter and surfaced as the
pre-#3675 non-envelope 500 { error: 'No response from handler' } — no
success flag, no error.message, the real cause lost.

Each now answers 400 in the declared envelope, under the code registered
(ADR-0112) for the service the route dispatches to:

- GET /api/v1/datasources → DATASOURCE_ADMIN_ERROR, matching its eight
  siblings in admin-routes.ts
- POST /datasources/:name/external/refresh-catalog and
  POST /datasources/:name/external/validate → EXTERNAL_DATASOURCE_ERROR,
  the code #4249 gave the two introspection routes above them

The issue left INTERNAL_ERROR open as an alternative; the per-service
codes win on consistency — every other catch in both modules, including
pure reads, already answers 400 with the service-attributed code, and
refreshCatalog's dominant throw class is the one #4249 already
adjudicated as a 400 refusal on listRemoteTables. A 500 would fork the
failure contract within a module — the drift #4249 removed.

No new codes (both registered by #4263). The envelope-conformance suites
and the REFUSALS pin table gain one row per route.

Closes #4264

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDgGWS97x6vuikjmgMswtk
@vercel

vercel Bot commented Jul 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Jul 31, 2026 5:35am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling size/m labels Jul 31, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/rest, @objectstack/service-datasource.

9 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/connect-mcp.mdx (via @objectstack/rest)
  • content/docs/api/error-handling-server.mdx (via @objectstack/rest)
  • content/docs/api/index.mdx (via @objectstack/rest)
  • content/docs/permissions/authentication.mdx (via @objectstack/rest)
  • content/docs/plugins/index.mdx (via @objectstack/rest)
  • content/docs/plugins/packages.mdx (via @objectstack/rest)
  • content/docs/protocol/kernel/i18n-standard.mdx (via packages/rest)
  • content/docs/releases/implementation-status.mdx (via @objectstack/rest)
  • content/docs/releases/v12.mdx (via @objectstack/rest)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@os-zhuang
os-zhuang marked this pull request as ready for review July 31, 2026 05:48
@os-zhuang
os-zhuang merged commit 366105c into main Jul 31, 2026
17 checks passed
@os-zhuang
os-zhuang deleted the claude/datasource-routes-service-throw-eo9izy branch July 31, 2026 05:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Three datasource routes still surface a service throw as the adapter's non-envelope 500 (#4249 follow-up)

2 participants