====== 第十四部分:故障排除与调试 ====== ===== 14.1 常见问题 ===== ===== 14.1.1 数据库打开失败 ===== **问题**:indexedDB.open() 报错 **原因**: * 浏览器隐私模式限制了 IndexedDB * 存储配额已满 * 浏览器不支持 **解决方案**: async function safeOpenDB(dbName, version) { try { // 检测支持性 if (!window.indexedDB) { throw new Error('浏览器不支持 IndexedDB'); } // 检测配额 if (navigator.storage && navigator.storage.estimate) { const estimate = await navigator.storage.estimate(); if (estimate.usage >= estimate.quota) { throw new Error('存储空间已满'); } } return await openDatabase(dbName, version); } catch (error) { console.error('数据库打开失败:', error); // 降级方案 return new MemoryStorage(); } } ===== 14.1.2 事务中止 ===== **问题**:TransactionInactiveError 或事务意外中止 **原因**: * 在异步操作后继续使用事务 * 事务中的操作失败导致整体回滚 **解决方案**: // 错误示例 async function badExample() { const transaction = db.transaction(['users'], 'readwrite'); const store = transaction.objectStore('users'); await fetch('/api/check'); // 异步操作! store.add(data); // TransactionInactiveError! } // 正确做法 async function goodExample() { // 先准备数据 const apiData = await fetch('/api/check').then(r => r.json()); // 再开启事务 const transaction = db.transaction(['users'], 'readwrite'); const store = transaction.objectStore('users'); store.add({ ...data, ...apiData }); } ===== 14.1.3 主键冲突 ===== **问题**:ConstraintError: Key already exists **解决方案**: // 方案1:使用 put 替代 add store.put(data); // 覆盖已有记录 // 方案2:先检查再插入 const existing = await store.get(key); if (!existing) { store.add(data); } else { console.warn('记录已存在'); } // 方案3:捕获错误 request.onerror = (event) => { if (request.error.name === 'ConstraintError') { event.preventDefault(); // 阻止事务中止 console.warn('主键冲突,跳过'); } }; ===== 14.2 调试技巧 ===== ===== 14.2.1 浏览器开发者工具 ===== Chrome/Edge: * F12 → Application → IndexedDB * 可查看数据库、对象存储、索引 * 可查看和删除数据 Firefox: * F12 → Storage → IndexedDB ===== 14.2.2 日志封装 ===== const DEBUG = true; function log(...args) { if (DEBUG) { console.log('[IndexedDB]', ...args); } } function wrapRequest(request, operation) { return new Promise((resolve, reject) => { log(`${operation} 开始`); request.onsuccess = () => { log(`${operation} 成功`, request.result); resolve(request.result); }; request.onerror = () => { log(`${operation} 失败`, request.error); reject(request.error); }; }); } ===== 14.3 错误代码参考 ===== ^ 错误名 ^ 说明 ^ 解决方案 ^ | AbortError | 事务被中止 | 检查事务逻辑 | | ConstraintError | 违反约束 | 检查主键/唯一索引 | | NotFoundError | 对象存储不存在 | 检查名称拼写 | | QuotaExceededError | 存储超限 | 清理数据或请求持久化 | | TransactionInactiveError | 事务已结束 | 避免异步后使用事务 | | VersionError | 版本错误 | 确保版本号递增 | ===== 14.4 本章小结 ===== 本章介绍了 IndexedDB 的故障排除: * 常见错误及解决方案 * 浏览器开发者工具调试方法 * 日志封装便于排查问题 继续阅读 [[part15-appendix|第十五部分:附录]]。