Skip to content

analytics dataset 路由:另有九处「作者/调用方形状」的 dataset 拒收仍答 500 —— 它们从来没进过 #5352 的正则名单,所以 #5367 的信封化也没覆盖到 #5716

Description

@os-zhuang

背景

#5352 / PR #5366 让 POST /analytics/dataset/query 的 catch 先读 ADR-0112 信封,并留下一串写死的 message 正则兜底(六族)。#5367 / PR(本单的来源)把其中五族信封化成 DATASET_INVALID / 400 并删掉对应正则条目,只留 read-scope-sql 一条。

实现 #5367 时逐条读了 service-analytics 的全部 throw new Error(...),发现一个 #5352 和 #5367 都没覆盖的集合:另有九处同样是调用方 / dataset 作者形状的拒收,它们既没有信封、也从来没进过那串正则,所以今天答的是 500 ANALYTICS_QUERY_FAILED —— 与已修好的五族是同一个缺陷,只是当初没被点名,因此也没有被任何退休时间表接管。

清单(行号基于 origin/main + #5367 的提交)

packages/services/service-analytics/src/dataset-compiler.ts

行 拒收 触发者
237 dataset 的 JOIN 跨 datasource(#5115 的编译期闸门) dataset 作者
260 include 里的 relationship 在对象上不存在 dataset 作者
271 include 路径超过 MAX_JOIN_HOPS 跳数上限 dataset 作者

packages/services/service-analytics/src/dataset-executor.ts

行 拒收 触发者
466 dateRange 里的日期解析不出来 请求(selection.timeDimensions[].dateRange)
511 compareTo.dimension 点名的 timeDimension 没有 dateRange 请求(selection.compareTo)
524 compareTo 但整个 selection 没有任何带 dateRange 的 timeDimension 请求
532 compareTo.dimension 有歧义(多个 timeDimension 带 dateRange) 请求

packages/services/service-analytics/src/strategies/native-sql-strategy.ts

行 拒收 触发者
468 cube 上没有这个 measure(#4157 把 COUNT(*) 静默兜底改成拒收的那一处) 请求(selection.measures)
487 measure 的 type 不认识 cube / dataset 作者

七处的输入直接来自 HTTP 请求体的 selection,两处来自调用方内联 POST 的 dataset(Studio 预览)或作者保存的 dataset。全部符合 4xx。

为什么值得单独立一条

明确不在此列

验收建议

  1. 逐处判 code/status(给出理由),通过 datasetInvalidError 或按需新增同形构造器抛出。
  2. 每处至少一条生产方单测(code/status/message 指名内容)+ 端到端 REST 断言,形状照 packages/rest/src/analytics-dataset-refusal-envelope.test.ts。
  3. changeset 必须写明这是可见的行为变更(500 → 4xx),照 analytics 的 filter 拒收到不了调用方:service 侧多数拒收没有 ADR-0112 信封,REST 面又用 message 正则嗅探,一律答 500 #5352 changeset 里 "Observable behaviour change — read this if you alert or retry on status" 那一段的写法。

Activity

  1. os-zhuang commented on Aug 6, 2026

    @os-zhuang
    ContributorAuthor

    存量裁决轮(维护者 2026-08-06 委托,session_01LeEfA7CFwbJb7JJmXm2KM3):裁定入队。前提经 origin/main 核实仍成立:清单九处作者/调用方形状拒收仍是裸 throw new Error(走 500)——dataset-compiler.ts 三处、dataset-executor.ts 四处等;#5367 建的 datasetInvalidError(DATASET_INVALID/400)落点已在,逐处判 code + 端到端断言 + changeset 即可收口。维护者可否决。


    Generated by Claude Code

  2. hotlong commented on Aug 6, 2026

    @hotlong
    Contributor

    实现 #5739(即席推断路径的关系穿越)时路过,带来一处清单外的同族站点,记录在此而不另立单——本单就是这个族的归属,补进清单比开孪生单干净。

    站点

    packages/services/service-analytics/src/strategies/objectql-strategy.ts,planCrossObject 的三处拒收(跨对象 filter / 跨对象 measure / 跨对象 time dimension bucket),以及同函数的多跳与不可重组 measure 两处。全部是裸 throw new Error(...),不带 code/status。

    触发者是调用方形状:query 里写了一个关系穿越成员而驱动是 ObjectQL(engine.aggregate 不能 join)。与清单里 native-sql-strategy.ts:468(cube 上没有这个 measure)同层同性质。

    实测(含 #5739 改动的分支)

    cube: crm_account(即席推断),ObjectQL 策略
    where: {'owner.region': 'NA'}
    → Error: [Analytics] ObjectQLStrategy cannot evaluate a cross-object filter ("owner.region")
             — the engine cannot join in an aggregate. …
       code: undefined   status: undefined
    

    与 #5739 的关系(可见性上升,不是新缺陷)

    这条 throw 在 origin/main 上就已经可达:已注册 cube 上对同一个成员就是它,即席路径上数组 where 写法也是它。#5739 裁 B 落地后,即席路径的对象写法也收敛到同一条 throw(此前它要么静默筛基表同名列、要么答 400 INVALID_FIELD 点名剥出来的尾段)。

    也就是说 #5739 让这条无信封的拒收在一条常见写法上变得更容易撞到,但它不是 #5739 引入的,也不该由 #5739 的 PR 顺手改(那会把信封变更混进一个 JOIN 语义的 PR)。

    建议

    按本单既有判据处理即可:调用方形状 ⇒ 4xx。code 上,跨对象拒收更像 DATASET_INVALID 的同形兄弟还是 INVALID_FIELD(它确实点名了一个成员),留给本单实施者一并判。若维护者认为超出本单圈定的「九处」,我可以另立单——只是那样会把同一族拆成两单。


    Generated by Claude Code

  3. self-assigned this
    on Aug 6, 2026
  4. hotlong commented on Aug 6, 2026

    @hotlong
    Contributor

    认领:PM 循环第 2 轮(services 车道)
    会话:session_015a5qkLzpGXhLL2F5gvJ7dD
    分支:claude/issue-5716-dataset-refusals-4xx
    Worktree:objectstack-issue-5716
    域:domain:services
    文件面:packages/services/service-analytics/src/dataset-compiler.ts / dataset-executor.ts / strategies/native-sql-strategy.ts / strategies/objectql-strategy.ts(planCrossObject 族,按 11:40Z 留痕并入,PM 批准)/ dataset-refusal.ts + 同包测试 + packages/rest 信封端到端断言;⛔ 不触 analytics-service.ts(#5923 刚合面)、不触默认粒度逻辑(#5688 靶面)、不触 read-scope-sql(#5808 已另判 500)
    串行约束已清:#5808 今日已合(read-scope 开放问题已闭);#5923(#5739)在合并队列 —— 开工前先确认其落地、基于合并后 origin/main;⚠️ #5688 与本单同文件(dataset-executor.ts),严格后轮串行

    范围注记:planCrossObject 族(3+2 处)按本单自身判据「调用方形状 ⇒ 4xx」并入清单 —— 同族一单收口,不开孪生单。


    Generated by Claude Code

  5. hotlong commented on Aug 6, 2026

    @hotlong
    Contributor

    验收:ACCEPT → PR #5963(CI 24/24 绿,随后转 ready 入队,本座位跟到 MERGED)。

    必答项三条已核;#5717 的重定价已单独记到该单。

    经办:services 座位,会话 session_015a5qkLzpGXhLL2F5gvJ7dD(第 2 轮)。


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions