Skip to content

REST 列表:无法解析的 filter JSON 被静默忽略 —— 返回未过滤整页(#4134/#4164 家族第三员) #4181

Description

@os-zhuang

TL;DR

GET /api/v1/data/<object>?filter={status:done(JSON 少个引号)—— findData 的解析容忍 try { JSON.parse } catch { /* keep as-is */ }原始字符串塞进 where,驱动层对字符串 where 静默忽略,返回未过滤的整页

这是 #3948 那条原则(an unapplied filter must not look like a satisfied one)目前最恶性的破缺形态:#4134 是清零(少了),#4164 是丢一个谓词(多了一点),这里是整个过滤器蒸发(全都多了)。如果 filter 承担的是业务性收窄,多返回就是数据泄露的形状。

实测(真实 InMemoryDriver + 真 registry,3 行数据其中 1 行 status=done

baseline (no filter)                     -> 200 total=3
filter='{"status":"done"}' (合法 JSON)    -> 200 total=1   ✅
filter='{status:done'      (垃圾字符串)   -> 200 total=3   ❌ 整页,无警告
filter='{status:done' + top=2            -> 200 total=3 records=2   ❌ 还在装模作样地分页

调用方拿到 total=3 和完全正常的信封,没有任何信号表明自己的 filter 从未生效。

病灶

packages/metadata-protocol/src/protocol.ts 的 filter alias 链:

if (typeof parsedFilter === 'string') {
    try { parsedFilter = JSON.parse(parsedFilter); } catch { /* keep as-is */ }
}
...
options.where = parsedFilter;   // 字符串原样成为 where

建议的方向:JSON.parse 失败即 400INVALID_REQUEST 或注册一个专码,信封里带上解析失败的原文片段)。「宽容地保留原字符串」不是任何调用方需要的行为——没有驱动能消费字符串 where,这个容忍只制造静默。#4164 的 AND 合并已刻意绕开非 object 的 where(不往垃圾里合并谓词),并在测试里 pin 了这条路径的现状,等本 issue 在源头修掉。

顺带坐实的同链小弟

body 同时带 wherefilter 时,options.filter ?? options.filters ?? options.$filter ?? options.wherefilter 静默赢:

{ where: {status:'done'}, filter: {status:'open'} }   -> 200 total=2 (= status:open;where 被丢)

显式对显式的 drop。低频(body 是 Partial<QueryAST>,规范键是 where),但同病。修法可以跟主案一致:两者并存且不相等 → 400,或 AND 合并——留给实现者与 #4164 的语义对齐。

关联

#4134(未知参数清零,已修)、#4164(已知字段参数被显式 filter 挤掉,修复中)、#3948(原则出处)。三案修完建议补一个家族级 conformance:每一条 filter 表达路径,要么生效,要么抛错

Activity

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions