IndexedDB错误监测必须逐层显式监听:IDBRequest的onerror是唯一有效捕获点,db.onerror和transaction.onerror均不存在;索引未找到等结构问题需靠版本升级与onversionchange预防,事务静默失效须主动校验active状态。

IndexedDB 的错误监测不是靠“统一上报”或“自动捕获”,而是依赖逐层显式监听。它没有全局错误钩子,错误也不会向上冒泡——每个操作产生的错误,只属于那个具体的请求对象(IDBRequest),必须在对应位置设 onerror 才能捕获。
错误只绑定在请求上,不绑定在数据库或事务上
-
IDBDatabase对象(比如db)没有onerror属性,写db.onerror = ...会直接报TypeError。 -
IDBTransaction对象(比如transaction)也没有onerror属性(尽管某些旧文档误传)。事务级错误实际是通过其内部请求触发的,需监听事务的onerror事件——但注意:这个事件的event.target是出错的IDBRequest,不是事务本身。 - 真正有效的监听点只有两类:
-
IDBOpenRequest(来自indexedDB.open())的onerror和onsuccess - 所有后续操作返回的
IDBRequest(如store.get()、store.put()、index.getAll())的onerror和onsuccess
-
版本升级相关错误必须提前预防,不能靠事后捕获
-
store.index("xxx")报 “specified index was not found”,通常不是运行时错误,而是结构缺失问题:索引根本没创建。 - 根本原因在于
onupgradeneeded没触发——可能因为版本号没变,或旧标签页占着连接未释放。 - 此类问题无法用
onerror捕获,只能靠设计规避:- 每次新增索引或修改 schema,必须提升数据库版本号
- 主动监听
db.onversionchange,在旧连接中调用db.close()并提示刷新 - 在
onupgradeneeded中严格检查objectStoreNames.contains(),再创建 store 或 index
事务生命周期错误往往静默发生,需主动验证状态
- 事务一旦关闭(例如因异步延迟、微任务清空或手动
abort()),再往里面加请求就会抛InvalidStateError。 - 常见诱因:
- 在
setTimeout或fetch().then()回调里继续使用已结束的事务 -
onsuccess里过早调用db.close(),导致后续请求失效 - 多个请求共享一个事务,但某个请求失败后未处理,其他请求仍尝试执行
- 在
- 验证方式:操作前检查
transaction.db是否存在、transaction.active是否为true
数据写入类错误需区分类型,针对性处理
-
DataError:主键字段为undefined/null/NaN,且未启用autoIncrement→ 应在写入前做字段校验 -
ConstraintError:重复主键或唯一索引冲突 → 可选择忽略(调用event.preventDefault()阻止事务中止),或改用put()覆盖 -
AbortError:事务被外部中止(如用户关闭页面、onversionchange触发)→ 应监听transaction.onabort,而非仅靠onerror
错误监测本质是防御性编程:不依赖“万一出错再处理”,而是在打开、升级、事务、请求四个层级,各守一关。











