ISSUE-0086:jsstore insertOne 空函数体 footgun¶
症状¶
src/utils/jsstore/base.ts 的 insertOne 从母产品迁移过来时函数体为空:
调用它不会插入任何数据,且静默返回 undefined——不报错、不抛异常。
当前 src/ 下零调用,所以没造成线上事故;但留着就是地雷:
将来任何人 await insertOne(...) 期待写入一条数据,会得到"成功"假象而数据丢失。
根因¶
整库(src/utils/jsstore/)从母 SaaS 产品迁移而来。母产品里插入走 insertMany,
insertOne 是个没填实现的占位空壳,一并被搬了过来。迁移时未清理。
修复¶
补成与 insertMany 完全相同的契约(try-catch → {success, data} / {success, message}),
内部复用 connection.insert,单条值包成数组:
export const insertOne = async (table: string, value: any) => {
try {
const data = await connection.insert({ into: table, upsert: true, values: [value] });
return { success: true, data };
} catch (err: any) {
const { message } = err ?? {};
return { success: false, message: `保存数据失败:${message || '未知错误'}` };
}
};
零调用 → 改它无回归风险;类型签名与 insertMany 一致,tsc 0 新错误。
影响文件¶
src/utils/jsstore/base.ts
经验教训¶
- 迁移整库时要扫空函数体 / 占位符——
=> {}的 async 函数是典型 footgun, TypeScript 不报错(返回Promise<void>),但语义上"静默吞掉调用"。 - 静默失败比吵闹失败危险:宁可抛错也别返回 undefined 假装成功。
- 同库其余错误契约(吞/抛混用)经核实是 load-bearing(
countByQuery抛异常被addSearchData去重逻辑依赖),不可统一——见 fix-regression-defense 单点假定修复反模式。
验证¶
- pnpm compile ✅ 0 新错误(tsc 复核两遍)
- pnpm build ✅ 7.4s
- manifest 版本 sanity ✅ 0.10.124