Skip to content

[finding] queryDataset 里还有第二个 message 嗅探器 isMissingSourceError,命中即静默返回空结果 —— dataset-compiler 的一条拒收措辞已经命中它,只因抛点在 try 之外才没出事 #5717

Description

@os-zhuang

观察

#5352 / #5367 处理的是 rest-server.ts 里那串「按 message 措辞决定 HTTP 码」的正则。packages/services/service-analytics/src/analytics-service.ts 里还有第二个同类嗅探器,而且它的后果比选错状态码更重:命中即把错误换成一个空结果。

// analytics-service.ts:83
function isMissingSourceError(err: unknown): boolean {
  const msg = String((err as { message?: unknown })?.message ?? err ?? '').toLowerCase();
  return (
    msg.includes('no such table') ||
    (msg.includes('relation') && msg.includes('does not exist')) ||
    msg.includes("doesn't exist") ||
    msg.includes('not registered') ||
    msg.includes('unknown object') ||
    msg.includes('is not a registered object')
  );
}

命中后 queryDataset 的 catch(analytics-service.ts:700)会 logger.warn 一句然后
return { rows: [], fields: [], totals: [] } —— 也就是 widget 画一个自信的空图,而不是报错。
这个降级本身是刻意的(对象没在本 kernel 挂载时 widget 应当显示「无数据」而非 500),#5033 已经把跨库那一支拆出来单独响亮报错。问题在于判据是措辞

已经存在的一次命中(今天无害)

dataset-compiler.ts:260 的拒收原文:

[dataset-compiler] dataset "X" includes relationship "R" which does not exist on object "O".

它同时含 relation(在 relationship 里)和 does not existisMissingSourceError 返回 true

今天不出事的唯一原因是抛点在 try 之外:queryDatasetconst compiled = this.registerDataset(dataset)(第 626 行,compileDataset 在这里抛),而那个 try/catch 在第 697 行才开始。也就是说这是一条已经装好但没接电的雷:

属于 observation 类:今天没有用户会撞到,grep 也不会告诉你两条措辞正在互相纠缠。

可能的方向(不预判,留给 triage)

  • A. 判据换成结构而非措辞:让「源缺失」由驱动侧带 code(例如 ERR_DATASOURCE_UNAVAILABLE 已在 ERROR_CODE_LEDGER 里)或由 isRegisteredObject 探针回答,isMissingSourceError 退化为兼容层并排到 code 判据之后。
  • B. 最小防守:降级路径只对「不带 ADR-0112 信封的错误」生效 —— 一个已经自称 4xx 的拒收(analytics dataset 路由的 message 正则兜底没有退休时间表:六族拒收仍靠措辞分类,改一个字就换一个 HTTP 码 #5367 之后 dataset-compiler 的两处就是)永远不该被降级成空结果。这一条无论 A 做不做都成立,且能直接把上面那条雷拆掉。
  • C. 收紧 relation/does not exist 这一支,让它只匹配 Postgres 的实际措辞(relation "x" does not exist,带引号的关系名),而不是任意同时含两个词的句子。

参考

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions