diff --git a/tracker/tracker/src/main/index.ts b/tracker/tracker/src/main/index.ts index f3105eb36..8d2fa3c11 100644 --- a/tracker/tracker/src/main/index.ts +++ b/tracker/tracker/src/main/index.ts @@ -276,17 +276,17 @@ export default class API { } } - handleError = (e: Error | ErrorEvent | PromiseRejectionEvent, extraInfo?: ErrorExtra) => { + handleError = (e: Error | ErrorEvent | PromiseRejectionEvent, metadata?: ErrorExtra) => { if (this.app === null) { return } if (e instanceof Error) { - this.app.send(getExceptionMessage(e, [])) + this.app.send(getExceptionMessage(e, [], metadata)) } else if ( e instanceof ErrorEvent || ('PromiseRejectionEvent' in window && e instanceof PromiseRejectionEvent) ) { - const msg = getExceptionMessageFromEvent(e) + const msg = getExceptionMessageFromEvent(e, undefined, metadata) if (msg != null) { this.app.send(msg) } diff --git a/tracker/tracker/src/main/modules/exception.ts b/tracker/tracker/src/main/modules/exception.ts index 7462226d3..e318fff2d 100644 --- a/tracker/tracker/src/main/modules/exception.ts +++ b/tracker/tracker/src/main/modules/exception.ts @@ -1,6 +1,6 @@ import type App from '../app/index.js' import type Message from '../app/messages.gen.js' -import { JSException } from '../app/messages.gen.js' +import { JSException, ExceptionWithMeta } from '../app/messages.gen.js' import ErrorStackParser from 'error-stack-parser' export interface Options { @@ -15,6 +15,11 @@ interface StackFrame { source?: string } +interface ErrorMeta { + tags: string[] + meta: Record +} + function getDefaultStack(e: ErrorEvent): Array { return [ { @@ -27,21 +32,27 @@ function getDefaultStack(e: ErrorEvent): Array { ] } -export function getExceptionMessage(error: Error, fallbackStack: Array): Message { +export function getExceptionMessage( + error: Error, + fallbackStack: Array, + metadata?: ErrorMeta, +): Message { let stack = fallbackStack try { stack = ErrorStackParser.parse(error) } catch (e) {} - return JSException(error.name, error.message, JSON.stringify(stack)) + const method = metadata ? ExceptionWithMeta : JSException + return method(error.name, error.message, JSON.stringify(stack), JSON.stringify(metadata)) } export function getExceptionMessageFromEvent( e: ErrorEvent | PromiseRejectionEvent, context: typeof globalThis = window, + metadata?: ErrorMeta, ): Message | null { if (e instanceof ErrorEvent) { if (e.error instanceof Error) { - return getExceptionMessage(e.error, getDefaultStack(e)) + return getExceptionMessage(e.error, getDefaultStack(e), metadata) } else { let [name, message] = e.message.split(':') if (!message) { @@ -52,7 +63,7 @@ export function getExceptionMessageFromEvent( } } else if ('PromiseRejectionEvent' in context && e instanceof context.PromiseRejectionEvent) { if (e.reason instanceof Error) { - return getExceptionMessage(e.reason, []) + return getExceptionMessage(e.reason, [], metadata) } else { let message: string try { @@ -60,7 +71,8 @@ export function getExceptionMessageFromEvent( } catch (_) { message = String(e.reason) } - return JSException('Unhandled Promise Rejection', message, '[]') + const method = metadata ? ExceptionWithMeta : JSException + return method('Unhandled Promise Rejection', message, '[]', JSON.stringify(metadata)) } } return null