Skip to content

errorResponseBaseerr.code 落在 error.code 而非 error.details.code —— #5367 changeset 与 read-scope-sql.ts 文件头都把线上位置写错了 #6123

Description

@qq9340100

观察(observation-class,今天没有用户会撞到)

实现 #5811 时实测 POST /analytics/query 的 read-scope 拒收响应体,发现两处已合入的说明文字把 err.code 在线上的落点写错了。分类信息本身没有丢,只是键名不是文档说的那个 —— 所以这是文字漂移,不是缺陷。

实测

packages/runtime/src/dispatcher-plugin.tserrorResponseBase 确实把 err.code 放进 details(#3842):

const details =
    err?.code || validation
        ? { ...(err?.code ? { code: err.code } : {}), ...(validation ?? {}) }
        : undefined;
res.json({ success: false, error: buildApiError({ message, httpStatus, details }) });

但共享构造器 buildApiError(packages/runtime/src/error-envelope.ts:117)随后把它提升进声明字段:

const { code: promoted, details } = splitSemanticCode(input.details);
return {
    code: input.code ?? promoted ?? standardErrorCodeForHttpStatus(input.httpStatus),
    ...
    ...(details !== undefined ? { details } : {}),
};

splitSemanticCode 取走 codedetails 为空,于是整个 details 键被省略。真实线上 body(真 AnalyticsService + 真挂载路由,策略 { 'secret policy field': 'u1' }):

{"success":false,"error":{"code":"READ_SCOPE_COMPILE_FAILED",
 "message":"Internal server error","httpStatus":500}}

error.details 不存在。

两处写错的文字

  1. .changeset/analytics-read-scope-compile-failed-500.md(analytics dataset 路由的 message 正则兜底没有退休时间表:六族拒收仍靠措辞分类,改一个字就换一个 HTTP 码 #5367,尚未发布,会作为 CHANGELOG.md 随 npm 包发给消费者):

    It is legible on the wire through the sibling /analytics/query exit, which puts a thrown err.code in error.details.code (The dispatcher puts the HTTP status in error.code and parks the real code in details — pinned in #3687, still unfixed #3842).

  2. packages/services/service-analytics/src/read-scope-sql.ts 文件头:

    The code is what a machine reads: dispatcher-plugin.errorResponseBase, the sibling /analytics/query exit, puts a thrown err.code in error.details.code (The dispatcher puts the HTTP status in error.code and parks the real code in details — pinned in #3687, still unfixed #3842), so READ_SCOPE_COMPILE_FAILED is legible there without anyone parsing prose.

#5811 的 issue 正文验收建议第 1 条也照抄了这个说法。

为什么按 observation-class 归档

  • 没有行为缺陷READ_SCOPE_COMPILE_FAILED 照样上线、照样可被机器读到,只是在 error.code 上 —— 那是 ApiErrorSchema 声明的字段,比 details 里更正规。
  • 没有消费者被它误导过analytics dataset 路由的 message 正则兜底没有退休时间表:六族拒收仍靠措辞分类,改一个字就换一个 HTTP 码 #5367 的裁决记录里明确写了「no consumer reads a code on this path」,所以这段文字目前是给未来读者看的。
  • 但它会随 CHANGELOG.md 发到 npm 包里,而按仓库惯例 changeset 正文正是「升级中的 agent 在 tombstone 报错后 grep 的东西」。一句指向不存在的键的说明,正是那种 grep 不到就自己发明 ?? 兜底的起点。

建议动作(不预判优先级)

把两处 error.details.code 改成 error.code,并顺带说明是 buildApiErrorsplitSemanticCode 做的提升 —— 一句话就能让下一个读者知道 details 为空时会被省略。#5811 的 PR(#6122)只在自己的用例与 changeset 里按实测写了正确位置,没有去动别人 PR 的 changeset 与 service-analytics 的文件头(⛔ service-analytics 在该单里是只读参考面)。

参考


Generated by Claude Code

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions