import { Event , EventHint , EventProcessor , ExtendedError , Hub , Integration } from '@sentry/types' ; import { isError , isPlainObject , logger , normalize } from '@sentry/utils' ; /** JSDoc */ interface ExtraErrorDataOptions { depth ? : number ; } /** Patch toString calls to return proper name for wrapped functions */ export class ExtraErrorData implements Integration { inheritDoc public static id : string = 'ExtraErrorData' ; inheritDoc public name : string = ExtraErrorData . id ; inheritDoc public constructor ( private readonly _options = { depth : 3 } ) { } inheritDoc public setupOnce ( addGlobalEventProcessor , getCurrentHub ) { addGlobalEventProcessor ( ( event , hint ? ) => { const self = getCurrentHub ( ) . getIntegration ( ExtraErrorData ) ; if ( ! self ) { return event ; } return self . enhanceEventWithErrorData ( event , hint ) ; } ) ; } /**
     * Attaches extracted information from the Error object to extra field in the Event
     */ public enhanceEventWithErrorData ( event , hint ? ) { if ( ! hint || ! hint . originalException || ! isError ( hint . originalException ) ) { return event ; } const name = ( hint . originalException as ExtendedError ) . name || hint . originalException . constructor . name ; const errorData = this . _extractErrorData ( hint . originalException as ExtendedError ) ; if ( errorData ) { let contexts = { ... event . contexts , } ; const normalizedErrorData = normalize ( errorData , this . _options . depth ) ; if ( isPlainObject ( normalizedErrorData ) ) { contexts = { ... event . contexts , [ name ] : { ... normalizedErrorData , } , } ; } return { ... event , contexts , } ; } return event ; } /**
     * Extract extra information from the Error object
     */ private _extractErrorData ( error ) { try { const nativeKeys = [ 'name' , 'message' , 'stack' , 'line' , 'column' , 'fileName' , 'lineNumber' , 'columnNumber' , 'toJSON' , ] ; const extraErrorInfo = { } ; for ( const key of Object . keys ( error ) ) { if ( nativeKeys . indexOf ( key ) !== - 1 ) { continue ; } const value = error [ key ] ; extraErrorInfo [ key ] = isError ( value ) ? ( value as Error ) . toString ( ) : value ; } if ( typeof error . toJSON === 'function' ) { const serializedError = error . toJSON ( ) as Record < string , unknown > ; for ( const key of Object . keys ( serializedError ) ) { const value = serializedError [ key ] ; extraErrorInfo [ key ] = isError ( value ) ? ( value as Error ) . toString ( ) : value ; } } return extraErrorInfo ; } catch ( oO ) { logger . error ( 'Unable to extract extra data from the Error object:' , oO ) ; } return null ; } }