11/* eslint-disable max-lines */
22/* eslint-disable @typescript-eslint/no-explicit-any */
3- import { ExtendedError , WrappedFunction } from '@sentry/types' ;
3+ import { WrappedFunction } from '@sentry/types' ;
44
55import { htmlTreeAsString } from './browser' ;
66import { isElement , isError , isEvent , isInstanceOf , isPlainObject , isPrimitive } from './is' ;
@@ -92,50 +92,59 @@ export function urlEncode(object: { [key: string]: any }): string {
9292}
9393
9494/**
95- * Transforms any object into an object literal with all its attributes
96- * attached to it .
95+ * Transforms any `Error` or `Event` into a plain object with all of their enumerable properties, and some of their
96+ * non-enumerable properties attached .
9797 *
9898 * @param value Initial source that we have to transform in order for it to be usable by the serializer
99+ * @returns An Event or Error turned into an object - or the value argurment itself, when value is neither an Event nor
100+ * an Error.
99101 */
100- export function convertToPlainObject ( value : unknown ) : {
101- [ key : string ] : unknown ;
102- } {
103- let newObj = value as {
104- [ key : string ] : unknown ;
105- } ;
106-
102+ export function convertToPlainObject < V extends unknown > (
103+ value : V ,
104+ ) :
105+ | {
106+ [ ownProps : string ] : unknown ;
107+ type : string ;
108+ target : string ;
109+ currentTarget : string ;
110+ detail ?: unknown ;
111+ }
112+ | {
113+ [ ownProps : string ] : unknown ;
114+ message : string ;
115+ name : string ;
116+ stack ?: string ;
117+ }
118+ | V {
107119 if ( isError ( value ) ) {
108- newObj = {
120+ return {
109121 message : value . message ,
110122 name : value . name ,
111123 stack : value . stack ,
112- ...getOwnProperties ( value as ExtendedError ) ,
124+ ...getOwnProperties ( value ) ,
113125 } ;
114126 } else if ( isEvent ( value ) ) {
115- /**
116- * Event-like interface that's usable in browser and node
117- */
118- interface SimpleEvent {
119- [ key : string ] : unknown ;
127+ const newObj : {
128+ [ ownProps : string ] : unknown ;
120129 type : string ;
121- target ?: unknown ;
122- currentTarget ?: unknown ;
123- }
124-
125- const event = value as SimpleEvent ;
126-
127- newObj = {
128- type : event . type ,
129- target : serializeEventTarget ( event . target ) ,
130- currentTarget : serializeEventTarget ( event . currentTarget ) ,
131- ...getOwnProperties ( event ) ,
130+ target : string ;
131+ currentTarget : string ;
132+ detail ?: unknown ;
133+ } = {
134+ type : value . type ,
135+ target : serializeEventTarget ( value . target ) ,
136+ currentTarget : serializeEventTarget ( value . currentTarget ) ,
137+ ...getOwnProperties ( value ) ,
132138 } ;
133139
134140 if ( typeof CustomEvent !== 'undefined' && isInstanceOf ( value , CustomEvent ) ) {
135- newObj . detail = event . detail ;
141+ newObj . detail = value . detail ;
136142 }
143+
144+ return newObj ;
145+ } else {
146+ return value ;
137147 }
138- return newObj ;
139148}
140149
141150/** Creates a string representation of the target of an `Event` object */
@@ -148,23 +157,26 @@ function serializeEventTarget(target: unknown): string {
148157}
149158
150159/** Filters out all but an object's own properties */
151- function getOwnProperties ( obj : { [ key : string ] : unknown } ) : { [ key : string ] : unknown } {
152- const extractedProps : { [ key : string ] : unknown } = { } ;
153- for ( const property in obj ) {
154- if ( Object . prototype . hasOwnProperty . call ( obj , property ) ) {
155- extractedProps [ property ] = obj [ property ] ;
160+ function getOwnProperties ( obj : unknown ) : { [ key : string ] : unknown } {
161+ if ( typeof obj === 'object' && obj !== null ) {
162+ const extractedProps : { [ key : string ] : unknown } = { } ;
163+ for ( const property in obj ) {
164+ if ( Object . prototype . hasOwnProperty . call ( obj , property ) ) {
165+ extractedProps [ property ] = ( obj as Record < string , unknown > ) [ property ] ;
166+ }
156167 }
168+ return extractedProps ;
169+ } else {
170+ return { } ;
157171 }
158- return extractedProps ;
159172}
160173
161174/**
162175 * Given any captured exception, extract its keys and create a sorted
163176 * and truncated list that will be used inside the event message.
164177 * eg. `Non-error exception captured with keys: foo, bar, baz`
165178 */
166- // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
167- export function extractExceptionKeysForMessage ( exception : any , maxLength : number = 40 ) : string {
179+ export function extractExceptionKeysForMessage ( exception : Record < string , unknown > , maxLength : number = 40 ) : string {
168180 const keys = Object . keys ( convertToPlainObject ( exception ) ) ;
169181 keys . sort ( ) ;
170182
0 commit comments