发生背景
项目里有个保存草稿功能,对象比较复杂,JSON 太长,于是想到了 indexedDB 。
(二进制对象存储万岁!)
$ pnpm add idb
// Vue 组件中的代码片段
import { openDB } from 'idb';
const IDB_NAME = 'fb-mgr';
/** 打开数据库。 */
async function idb(options: Parameters<typeof openDB>[2]) {
return await openDB(IDB_NAME, 1, options);
}
/** 草稿 store 名称。 */
const DRAFT_STORE_NAME = 'draft';
/** 恢复草稿。 */
async function restoreDraft() {
const db = await idb({
upgrade(db) {
db.createObjectStore(DRAFT_STORE_NAME); // 没有 store 则创建
}
});
if (!db.objectStoreNames.contains(DRAFT_STORE_NAME)) { // 没有 store 则创建
const tx = db.transaction(DRAFT_STORE_NAME, 'versionchange');
await tx.done;
}
const tx = db.transaction(DRAFT_STORE_NAME, 'readonly'); // 读取草稿
const draft = await tx.store.get(useRoute().path);
await tx.done;
db.close();
if (!draft) return; // 没草稿
emit('update:modelValue', draft); // 更新数据
}
错误信息
Uncaught (in promise) DOMException: Failed to execute 'transaction' on 'IDBDatabase': One of the specified object stores was not found.
解决方案
由于数据库里没什么重要数据,想到了一个阴险巧妙的方法:删除数据库!
(毕竟是浏览器上的,对吧)
刷新页面,重建数据库,报错消失了!
又一个玄学 bug
发生原因
初步推断,你所遇到的问题可能是由于你的 indexDB 数据库因为某些原因被污染或者被破坏了,导致程序出现错误。当你删除数据库并重新加载页面时,会重新创建一个完全干净的 indexDB 数据库,从而解决了你遇到的问题。
请注意,如果你的程序中的其他部分出现了错误,删除数据库是无法解决问题的。因此,如果你的程序中出现了类似的问题,你需要检查程序中的其他可能的错误。
另外,为了防止类似的问题再次发生,你可以在你的程序中添加一些逻辑,以确保数据的完整性和正确性。例如,你可以添加一些数据验证的逻辑,或者使用数据库事务来确保数据在执行时保持不变。
——ChatGPT