做 #5437(sendError 5xx 直通消毒)时用真实 harness 打出来的旁证。不在那单范围内(那单只动 resolveErrorResponse 的显式 5xx 分支,⛔ 不动启发式本身),按 Prime Directive #10 单独记在这里,unassigned。
现象
驱动层 sys_metadata 整体不可用(表缺失/库不可达)时,一条不带 status 的原始驱动错误走到 mapDataError,被 looksLikeUnknownObject 命中 no such table,于是返回:
404 {"error":"Object not found","code":"OBJECT_NOT_FOUND"}
客户端读到的是「你要的对象不存在」,真实情况是「元数据存储整体挂了」。这两件事的处置完全相反:前者让人去查对象名拼写,后者该去看运维。
更要紧的是日志侧:isExpectedDataStatus 把 404 列为正常客户端错误,handleRouteError 因此不打 [REST] Unhandled error。所以这条基础设施故障在服务端一行都不留。
复现(in-process,已实跑)
真实 ObjectQL + 真实 ObjectStackProtocolImplementation,驱动的每个方法都抛 SQLITE_ERROR: no such table: sys_metadata:
PUT /api/v1/meta/object/acct
=> 404 {"error":"Object not found","code":"OBJECT_NOT_FOUND"}
Postgres 措辞(relation "sys_metadata" does not exist)同样命中 looksLikeUnknownObject 的第二条分支,结果一致。
成因
packages/rest/src/rest-server.ts 的 looksLikeUnknownObject 只看消息文本里有没有 no such table / relation ... does not exist,不区分缺的是哪张表。业务对象的表缺失和 sys_metadata 缺失是同一条正则的两个命中,但语义相反:前者确实约等于「对象没注册」,后者是元数据平面自身故障。
注意 #5437 只把显式声明了 5xx 的错误挡在启发式之前;这条路径上的错误不带 status,因此仍然整条走 mapDataError,不受 #5437 影响。
可选方向(不代裁决)
未验证的部分
只打了 PUT/DELETE /api/v1/meta/:type/:name 两条路由;数据路由(/api/v1/data/*)在 sys_metadata 挂掉时的表现没测。是否有别的系统表(sys_environment 等)落进同一条启发式也没清点。
关联
#5437(发现于此;只覆盖显式 5xx 一侧)、#3867(消毒器)、#4886(isExpectedDataStatus / 日志判定)、#3770(OBJECT_NOT_FOUND 单一信封)。
Generated by Claude Code
做 #5437(
sendError5xx 直通消毒)时用真实 harness 打出来的旁证。不在那单范围内(那单只动resolveErrorResponse的显式 5xx 分支,⛔ 不动启发式本身),按 Prime Directive #10 单独记在这里,unassigned。现象
驱动层
sys_metadata整体不可用(表缺失/库不可达)时,一条不带status的原始驱动错误走到mapDataError,被looksLikeUnknownObject命中no such table,于是返回:客户端读到的是「你要的对象不存在」,真实情况是「元数据存储整体挂了」。这两件事的处置完全相反:前者让人去查对象名拼写,后者该去看运维。
更要紧的是日志侧:
isExpectedDataStatus把 404 列为正常客户端错误,handleRouteError因此不打[REST] Unhandled error。所以这条基础设施故障在服务端一行都不留。复现(in-process,已实跑)
真实
ObjectQL+ 真实ObjectStackProtocolImplementation,驱动的每个方法都抛SQLITE_ERROR: no such table: sys_metadata:Postgres 措辞(
relation "sys_metadata" does not exist)同样命中looksLikeUnknownObject的第二条分支,结果一致。成因
packages/rest/src/rest-server.ts的looksLikeUnknownObject只看消息文本里有没有no such table/relation ... does not exist,不区分缺的是哪张表。业务对象的表缺失和sys_metadata缺失是同一条正则的两个命中,但语义相反:前者确实约等于「对象没注册」,后者是元数据平面自身故障。注意 #5437 只把显式声明了 5xx 的错误挡在启发式之前;这条路径上的错误不带
status,因此仍然整条走mapDataError,不受 #5437 影响。可选方向(不代裁决)
looksLikeUnknownObject对sys_metadata之类系统表名的命中单独判为 5xx(基础设施故障),不复用OBJECT_NOT_FOUND信封。status: 500(落地 sendError 的显式状态直通覆盖 400–599,5xx 的原始驱动报错绕过全部泄漏启发式直达客户端(metadata-protocol 有活体产出方) #5437 后即自动获得消毒 + 日志)。isExpectedDataStatus的 404 豁免只在code === 'OBJECT_NOT_FOUND'且消息不含系统表名时成立。未验证的部分
只打了
PUT/DELETE /api/v1/meta/:type/:name两条路由;数据路由(/api/v1/data/*)在sys_metadata挂掉时的表现没测。是否有别的系统表(sys_environment等)落进同一条启发式也没清点。关联
#5437(发现于此;只覆盖显式 5xx 一侧)、#3867(消毒器)、#4886(
isExpectedDataStatus/ 日志判定)、#3770(OBJECT_NOT_FOUND单一信封)。Generated by Claude Code