You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
4.7 KiB
178 lines
4.7 KiB
/** |
|
* 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 '/#/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<ErrorLogInfo> = {}; |
|
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.substr(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<ErrorLogInfo, 'message' | 'stack'>), |
|
}); |
|
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(); |
|
}
|
|
|