1
1
/* eslint-disable max-lines */
2
2
/* eslint-disable @typescript-eslint/no-explicit-any */
3
- import { ExtendedError , WrappedFunction } from '@sentry/types' ;
3
+ import { WrappedFunction } from '@sentry/types' ;
4
4
5
5
import { htmlTreeAsString } from './browser' ;
6
6
import { isElement , isError , isEvent , isInstanceOf , isPlainObject , isPrimitive } from './is' ;
@@ -92,50 +92,59 @@ export function urlEncode(object: { [key: string]: any }): string {
92
92
}
93
93
94
94
/**
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 .
97
97
*
98
98
* @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.
99
101
*/
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 {
107
119
if ( isError ( value ) ) {
108
- newObj = {
120
+ return {
109
121
message : value . message ,
110
122
name : value . name ,
111
123
stack : value . stack ,
112
- ...getOwnProperties ( value as ExtendedError ) ,
124
+ ...getOwnProperties ( value ) ,
113
125
} ;
114
126
} 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 ;
120
129
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 ) ,
132
138
} ;
133
139
134
140
if ( typeof CustomEvent !== 'undefined' && isInstanceOf ( value , CustomEvent ) ) {
135
- newObj . detail = event . detail ;
141
+ newObj . detail = value . detail ;
136
142
}
143
+
144
+ return newObj ;
145
+ } else {
146
+ return value ;
137
147
}
138
- return newObj ;
139
148
}
140
149
141
150
/** Creates a string representation of the target of an `Event` object */
@@ -148,23 +157,26 @@ function serializeEventTarget(target: unknown): string {
148
157
}
149
158
150
159
/** 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
+ }
156
167
}
168
+ return extractedProps ;
169
+ } else {
170
+ return { } ;
157
171
}
158
- return extractedProps ;
159
172
}
160
173
161
174
/**
162
175
* Given any captured exception, extract its keys and create a sorted
163
176
* and truncated list that will be used inside the event message.
164
177
* eg. `Non-error exception captured with keys: foo, bar, baz`
165
178
*/
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 {
168
180
const keys = Object . keys ( convertToPlainObject ( exception ) ) ;
169
181
keys . sort ( ) ;
170
182
0 commit comments