/** * Used to configure the global error handling function, which can monitor vue errors, script errors, static resource errors and Promise errors */ import type { ErrorLogInfo } from '@/types/store' import { useErrorLogStoreWithOut } from '@/store/modules/errorLog' import { ErrorTypeEnum } from '@/enums/exceptionEnum' import { App } from 'vue' import projectSetting from '@/settings/projectSetting' /** * Handling error stack information * @param error */ function processStackMsg(error: Error) { if (!error.stack) { return '' } let stack = error.stack .replace(/\n/gi, '') // Remove line breaks to save the size of the transmitted content .replace(/\bat\b/gi, '@') // At in chrome, @ in ff .split('@') // Split information with @ .slice(0, 9) // The maximum stack length (Error.stackTraceLimit = 10), so only take the first 10 .map((v) => v.replace(/^\s*|\s*$/g, '')) // Remove extra spaces .join('~') // Manually add separators for later display .replace(/\?[^:]+/gi, '') // Remove redundant parameters of js file links (?x=1 and the like) const msg = error.toString() if (stack.indexOf(msg) < 0) { stack = msg + '@' + stack } return stack } /** * get comp name * @param vm */ function formatComponentName(vm: any) { if (vm.$root === vm) { return { name: 'root', path: 'root' } } const options = vm.$options as any if (!options) { return { name: 'anonymous', path: 'anonymous' } } const name = options.name || options._componentTag return { name: name, path: options.__file } } /** * Configure Vue error handling function */ function vueErrorHandler(err: Error, vm: any, info: string) { const errorLogStore = useErrorLogStoreWithOut() const { name, path } = formatComponentName(vm) errorLogStore.addErrorLogInfo({ type: ErrorTypeEnum.VUE, name, file: path, message: err.message, stack: processStackMsg(err), detail: info, url: window.location.href }) } /** * Configure script error handling function */ export function scriptErrorHandler(event: Event | string, source?: string, lineno?: number, colno?: number, error?: Error) { if (event === 'Script error.' && !source) { return false } const errorInfo: Partial = {} colno = colno || (window.event && (window.event as any).errorCharacter) || 0 errorInfo.message = event as string if (error?.stack) { errorInfo.stack = error.stack } else { errorInfo.stack = '' } const name = source ? source.slice(source.lastIndexOf('/') + 1) : 'script' const errorLogStore = useErrorLogStoreWithOut() errorLogStore.addErrorLogInfo({ type: ErrorTypeEnum.SCRIPT, name: name, file: source as string, detail: 'lineno' + lineno, url: window.location.href, ...(errorInfo as Pick) }) return true } /** * Configure Promise error handling function */ function registerPromiseErrorHandler() { window.addEventListener( 'unhandledrejection', function (event) { const errorLogStore = useErrorLogStoreWithOut() errorLogStore.addErrorLogInfo({ type: ErrorTypeEnum.PROMISE, name: 'Promise Error!', file: 'none', detail: 'promise error!', url: window.location.href, stack: 'promise error!', message: event.reason }) }, true ) } /** * Configure monitoring resource loading error handling function */ function registerResourceErrorHandler() { // Monitoring resource loading error(img,script,css,and jsonp) window.addEventListener( 'error', function (e: Event) { const target = e.target ? e.target : (e.srcElement as any) const errorLogStore = useErrorLogStoreWithOut() errorLogStore.addErrorLogInfo({ type: ErrorTypeEnum.RESOURCE, name: 'Resource Error!', file: (e.target || ({} as any)).currentSrc, detail: JSON.stringify({ tagName: target.localName, html: target.outerHTML, type: e.type }), url: window.location.href, stack: 'resource is not found', message: (e.target || ({} as any)).localName + ' is load error' }) }, true ) } /** * Configure global error handling * @param app */ export function setupErrorHandle(app: App) { const { useErrorHandle } = projectSetting if (!useErrorHandle) { return } // Vue exception monitoring; app.config.errorHandler = vueErrorHandler // script error window.onerror = scriptErrorHandler // promise exception registerPromiseErrorHandler() // Static resource exception registerResourceErrorHandler() }