import type { BrowserExceptionRecord, BrowserExceptionRecordInput, ExceptionRecord, ExceptionRecordInput, NodejsExceptionRecord, NodejsExceptionRecordInput, } from "./types.ts" interface ErrorLike { message: string } const internalIsErrorLike = (exception: unknown): exception is ErrorLike => { if (exception instanceof Error) { return true } if (typeof exception !== "object" || exception === null) { return false } if ("message" in exception === false) { return false } const { message } = exception if (typeof message !== "string") { return false } return true } const internalGetExceptionMessage = (exception: unknown): string | undefined => { if (internalIsErrorLike(exception)) { return exception.message } if (typeof exception === "string") { return exception } return undefined } /** * @description 将异常输入标准化为共享异常记录。 */ export const normalizeExceptionRecord = (input: ExceptionRecordInput): ExceptionRecord => { const { runtime, source, exception, message, timestamp, originalEvent } = input return { runtime, source, exception, message: message ?? internalGetExceptionMessage(exception), timestamp: timestamp ?? Date.now(), originalEvent, } } /** * @description 将浏览器异常输入标准化为浏览器异常记录。 */ export const normalizeBrowserExceptionRecord = ( input: BrowserExceptionRecordInput, ): BrowserExceptionRecord => { const { source, filename, lineno, colno } = input return { ...normalizeExceptionRecord({ ...input, runtime: "browser", }), runtime: "browser", source, filename, lineno, colno, } } /** * @description 将 Nodejs 异常输入标准化为 Nodejs 异常记录。 */ export const normalizeNodejsExceptionRecord = ( input: NodejsExceptionRecordInput, ): NodejsExceptionRecord => { const { source, origin, promise } = input return { ...normalizeExceptionRecord({ ...input, runtime: "nodejs", }), runtime: "nodejs", source, origin, promise, } }