import { addGlobalEventProcessor , getCurrentHub } from '@sentry/core' ; import { Event , EventHint , Exception , ExtendedError , Integration } from '@sentry/types' ; import { exceptionFromStacktrace } from '../parsers' ; import { computeStackTrace } from '../tracekit' ; const DEFAULT_KEY = 'cause' ; const DEFAULT_LIMIT = 5 ; /** Adds SDK info to an event. */ export class LinkedErrors implements Integration { inheritDoc public readonly name : string = LinkedErrors . id ; inheritDoc public static id : string = 'LinkedErrors' ; inheritDoc private readonly _key : string ; inheritDoc private readonly _limit : number ; inheritDoc public constructor ( options = { } ) { this . _key = options . key || DEFAULT_KEY ; this . _limit = options . limit || DEFAULT_LIMIT ; } inheritDoc public setupOnce ( ) { addGlobalEventProcessor ( ( event , hint ? ) => { const self = getCurrentHub ( ) . getIntegration ( LinkedErrors ) ; if ( self ) { return self . _handler ( event , hint ) ; } return event ; } ) ; } inheritDoc private _handler ( event , hint ? ) { if ( ! event . exception || ! event . exception . values || ! hint || ! ( hint . originalException instanceof Error ) ) { return event ; } const linkedErrors = this . _walkErrorTree ( hint . originalException , this . _key ) ; event . exception . values = [ ... linkedErrors , ... event . exception . values ] ; return event ; } inheritDoc private _walkErrorTree ( error , key , stack = [ ] ) { if ( ! ( error [ key ] instanceof Error ) || stack . length + 1 >= this . _limit ) { return stack ; } const stacktrace = computeStackTrace ( error [ key ] ) ; const exception = exceptionFromStacktrace ( stacktrace ) ; return this . _walkErrorTree ( error [ key ] , key , [ exception , ... stack ] ) ; } }