Skip to content

finding(service-automation): engine.ts 还剩三处同形的 warn message 拼接 —— forgetSuspendedRun / cancelRun / listSuspendedRunsDurable,是 #5912+#6230 之后该文件的最后一批 #6299

Description

@hotlong

#6230(PR #6297)时在同一个文件扫到的旁生发现。#6230 的分诊评论已把那一单范围钉死在 loadSuspendedRun 一处、⛔ 不扩面,故按 Prime Directive #10 / objectstack#4949 单开。

现象

packages/services/service-automation/src/engine.ts(基线 origin/main dbe92a7e1 + PR #6297;⚠️ 行号会漂,以内容定位)还有三处#5912 / #6230 完全同形的拼接 —— 都是 logger.warn,都把我们不控制文本的数据源驱动 message 插进 message:

  1. forgetSuspendedRun(PR fix(service-automation): 降级版挂起态读取器的 warn cause 移出 message,改走 meta (#6230) #6297 后在 :1273)——
    `[automation] failed to delete suspended run '${run.runId}' from durable store: ${(err as Error).message}`
  2. cancelRun(:3528)——
    `[automation] cancelRun: failed to load suspended run '${runId}' from durable store: ${(err as Error).message}`
  3. listSuspendedRunsDurable(:3603)——
    `[automation] failed to list suspended runs from durable store: ${(err as Error).message}`

三条的 thrown 值都来自 SuspendedRunStore 底下的同一个驱动,和 #5912 / #6230 是同一族。

危害机制

#6230 逐字相同,不重复推演:ObjectLogger.write() 一次调用只加一个「时间戳 + 级别」记录头,message 里的换行把一条记录变成多个物理行,后几行无级别无时间戳,grep WARN 只捞到不含事实的那一行。

且三条都是 warn ⇒ 走 stdout ⇒ 落在 serve boot-quiet 缓冲的过滤面上(BootLogCapture.offer() 只保留有级别头的行),无头续行是被直接丢弃。PR #6297 已把这个「丢弃」量出来了:三行驱动错误进过滤器,只剩 1 行出来,而留下的那行不含任何驱动事实。

#6230 不同的地方:级别判定要逐条做,不能整批照抄

⚠️ 不要把这三条当成一次批量替换。 #6230 之所以判「级别不上调」,是因为 loadSuspendedRun 的 JSDoc 明写它是刻意的功能性降级读取器。这三条各自的 #4632 判定要单独看,而且至少有一条看起来不一样:

所以这一单如果被晋级,接手的人必须逐条给出 #4632 判定并各自钉测试,而不是把 #6230 的模板套三遍。message 拼接那一半是三条共通的,级别那一半不是。

可达性(为什么是 finding)

#5575 / #5636 / #5661 / #5737 / #5912 / #6230 同样的理由:今天库内的驱动错误均为单行,所以是 finding 而非事故报告。第一个包装多行 SDK 错误的驱动撞上 —— Postgres 的 detail: / hint: 续行、better-sqlite3 包装器在生态里很常见,同族历次实测都是照这个形状造的。

关联

#6230 / PR #6297(本发现的来源,同文件另三处)、#5912 / PR #6228#5737 / PR #5911#5661#5636 / PR #5662#5575 / PR #5639#5048 / PR #5572#5660(同在 engine.tsregisterDegradedConnector,已闭)、#5573#5186#4632#4420、cloud#971。

治完这三处,engine.ts 这一族就全净了。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions