const IGNORABLE_SCRIPT_ERRORS = [
|
'ResizeObserver loop completed with undelivered notifications.',
|
'ResizeObserver loop limit exceeded'
|
]
|
function normalizeErrorMessage(message) {
|
if (typeof message === 'string') {
|
return message
|
}
|
if ('message' in message && typeof message.message === 'string') {
|
return message.message
|
}
|
return ''
|
}
|
function isIgnorableScriptError(message, source) {
|
const normalizedMessage = normalizeErrorMessage(message)
|
if (!normalizedMessage) {
|
return false
|
}
|
if (IGNORABLE_SCRIPT_ERRORS.some((item) => normalizedMessage.includes(item))) {
|
return true
|
}
|
if (normalizedMessage === 'Script error.' && source === '') {
|
return true
|
}
|
return false
|
}
|
function vueErrorHandler(err, instance, info) {
|
console.error('[VueError]', err, info, instance)
|
}
|
function scriptErrorHandler(message, source, lineno, colno, error) {
|
if (isIgnorableScriptError(message, source)) {
|
return true
|
}
|
console.error('[ScriptError]', { message, source, lineno, colno, error })
|
return true
|
}
|
function registerPromiseErrorHandler() {
|
window.addEventListener('unhandledrejection', (event) => {
|
console.error('[PromiseError]', event.reason)
|
})
|
}
|
function registerResourceErrorHandler() {
|
window.addEventListener(
|
'error',
|
(event) => {
|
const target = event.target
|
if (
|
target &&
|
(target.tagName === 'IMG' || target.tagName === 'SCRIPT' || target.tagName === 'LINK')
|
) {
|
console.error('[ResourceError]', {
|
tagName: target.tagName,
|
src: target.src || target.src || target.href
|
})
|
}
|
},
|
true
|
// 捕获阶段才能监听到资源错误
|
)
|
}
|
function setupErrorHandle(app) {
|
app.config.errorHandler = vueErrorHandler
|
window.onerror = scriptErrorHandler
|
registerPromiseErrorHandler()
|
registerResourceErrorHandler()
|
}
|
export {
|
registerPromiseErrorHandler,
|
registerResourceErrorHandler,
|
scriptErrorHandler,
|
setupErrorHandle,
|
vueErrorHandler
|
}
|