layui 不提供 promise 错误捕获机制,需用原生 unhandledrejection 事件监听;它不封装或劫持该事件,所有未 catch 的 promise reject 均会触发,监听器须在 layui.config 前注册。

Layui 本身不提供 Promise 错误捕获机制,它只是 UI 框架,底层仍依赖原生 JavaScript 运行时。要捕获全局未处理的 Promise 拒绝异常,必须直接使用浏览器原生的 unhandledrejection 事件监听 —— 和是否引入 Layui 完全无关。
为什么 layui 不影响 unhandledrejection 监听
Layui 的所有异步操作(如 layui.use、$.ajax、layer.open 内部的加载逻辑)最终都落在原生 Promise 或 XMLHttpRequest 上。只要这些异步操作返回了未被 .catch() 或 try/catch 捕获的 reject,unhandledrejection 就会照常触发。
常见误区是以为“用了 layui 就得用它的 API 捕错”,其实不是:Layui 没有封装或劫持该事件,也不提供类似 layui.errorHandler 的钩子。
-
layui.use加载模块失败时,若你没写layui.use(..., function(){})的第二个回调(错误回调),也不会触发unhandledrejection—— 因为它内部用的是回调函数,不是 Promise - 但如果你把
layui.use包在new Promise里又忘了catch,那就会触发 - 用
axios或fetch发请求(哪怕在 layui 模块里调用),照样走原生 Promise 流程
在 layui 项目中正确注册 unhandledrejection
必须确保监听器在任何可能抛出 Promise 错误的代码执行前就已注册。Layui 常用入口是 layui.config 后的 layui.use,但监听器不能等那时才加 —— 要更早。
推荐放在 HTML 的首个 <script></script> 标签内,或在 layui.config 调用之前:
window.addEventListener('unhandledrejection', event => {
console.error('Layui 应用中未捕获的 Promise 拒绝:', event.reason);
// 可选:上报到 Sentry / 自建监控
// reportToMonitor({ type: 'unhandledrejection', reason: event.reason });
// ⚠️ 不要无条件调用 event.preventDefault()
// 它只阻止控制台警告,不解决根本问题;开发阶段建议先留着警告
});
- 不要把它塞进
layui.use回调里 —— 那太晚,早期模块加载失败就捕不到 - 如果用 webpack/vite 打包,把这段监听逻辑放在
main.js最顶部,比layui.config还靠前 - 注意:Layui 1.x 默认不基于 Promise,2.x 也未将核心 API 改为 Promise 风格,所以多数“Layui 异步”本身不触发此事件;真正触发的往往是项目里混用的
fetch、async函数、或第三方库
容易和 layui 混淆的两类典型错误场景
这两类错误看起来像 “layui 报错”,实际和 unhandledrejection 无关,别配错监听目标:
-
layui.use加载失败:触发的是error事件或静默失败,不是 Promise 拒绝,需靠layui.use(modules, callback)的第二个参数捕获 -
layer.open中 content 为 URL 且加载失败:默认会报layer error: content url load failed,这是 layer 自己的错误提示,非 Promise 错误;若你手动用fetch加载 content 再 set 到 layer,则那个fetch的 reject 才归unhandledrejection管
也就是说:只有你主动创建/使用了 Promise,并且漏掉了错误处理,才会落到这个事件上。Layui 自身几乎不制造这类错误源。
真正要盯住的,是你在 layui.use 回调里写的 async 函数、fetch 请求、Promise.all 调用 —— 这些地方最容易漏 catch,而 unhandledrejection 是你最后一道防线。别指望框架替你兜底,它连监听器都要你自己挂。











