Files
BYW-VoiceHub/app/plugins/error-handler.client.ts
Henry_Du 4ce4649aaf
Build VoiceHub FPK / build-fpk (push) Failing after 56m5s
Build and Push Docker Image / build-and-push (push) Canceled after 1h9m35s
初次提交
2026-09-06 08:19:02 +08:00

52 lines
2.4 KiB
TypeScript

export default defineNuxtPlugin((nuxtApp) => {
// 监听并拦截异步 Chunk / 静态资源加载失败的问题(通常是因为服务端重新部署后,旧缓存还在尝试请求被删除的 hash 文件)
nuxtApp.hook('app:chunkError', ({ error }) => {
console.error('Nuxt Chunk/Asset Loading Failed. Triggering hard reload...', error)
// 防止无限刷新,使用 sessionStorage 记录
const reloadCount = parseInt(sessionStorage.getItem('chunk_reload_count') || '0')
if (reloadCount < 3) {
sessionStorage.setItem('chunk_reload_count', String(reloadCount + 1))
window.location.reload()
} else {
console.warn('Too many reload attempts for chunk error. Giving up.')
}
})
// 页面成功加载后清除刷新计数器
nuxtApp.hook('page:finish', () => {
sessionStorage.removeItem('chunk_reload_count')
})
// 拦截全局未捕获的 Promise 错误,防止它阻塞后续操作(例如因为插件拦截导致的 'A listener indicated an asynchronous response...' 错误)
if (import.meta.client) {
window.addEventListener('unhandledrejection', (event) => {
const err = event.reason?.message || event.reason?.toString() || ''
if (err.includes('message channel closed') || err.includes('A listener indicated')) {
// 这是常见的浏览器插件注入引起的无害错误,直接忽略
event.preventDefault()
}
})
// 监听全局 Error 事件,捕获 CSS 等资源的加载失败
window.addEventListener('error', (event) => {
const target = event.target as HTMLElement
// 检查是否是 link(css) 或 script 的加载错误
if (target && (target.tagName === 'LINK' || target.tagName === 'SCRIPT')) {
const href = (target as HTMLLinkElement).href || (target as HTMLScriptElement).src
if (href && href.includes('/_nuxt/')) {
console.warn('Nuxt static asset failed to load:', href)
const reloadCount = parseInt(sessionStorage.getItem('asset_reload_count') || '0')
if (reloadCount < 2) {
sessionStorage.setItem('asset_reload_count', String(reloadCount + 1))
// 延迟一点刷新以防频繁请求
setTimeout(() => {
window.location.reload()
}, 1000)
}
}
}
}, true) // true = 捕获阶段,以便拦截资源加载错误
}
})