@@ -33,7 +33,7 @@ type ObjOrArray<T> = { [key: string]: T };
3333 */
3434export function normalize ( input : unknown , depth : number = + Infinity , maxProperties : number = + Infinity ) : any {
3535 try {
36- // since we're at the outermost level, there is no key
36+ // since we're at the outermost level, we don't provide a key
3737 return visit ( '' , input , depth , maxProperties ) ;
3838 } catch ( err ) {
3939 return { ERROR : `**non-serializable** (${ err } )` } ;
@@ -98,17 +98,27 @@ function visit(
9898 return stringified ;
9999 }
100100
101- // We're also done if we've reached the max depth
102- if ( depth === 0 ) {
103- // At this point we know `serialized` is a string of the form `"[object XXXX]"`. Clean it up so it's just `"[XXXX]"`.
104- return stringified . replace ( 'object ' , '' ) ;
105- }
101+ // From here on, we can assert that `value` is either an object or an array!
106102
107103 // If we've already visited this branch, bail out, as it's circular reference. If not, note that we're seeing it now.
108104 if ( memoize ( value ) ) {
109105 return '[Circular ~]' ;
110106 }
111107
108+ // Do not normalize objects that we know have already been normalized. This MUST be below the circ-ref check otherwise
109+ // we might somehow accidentally produce circular references by skipping normalization.
110+ // As a general rule, the "__sentry_skip_normalization__" property should only be used sparingly and only should only
111+ // be set on objects that have already been normalized.
112+ if ( ( value as ObjOrArray < unknown > ) [ '__sentry_skip_normalization__' ] ) {
113+ return value as ObjOrArray < unknown > ;
114+ }
115+
116+ // We're also done if we've reached the max depth
117+ if ( depth === 0 ) {
118+ // At this point we know `serialized` is a string of the form `"[object XXXX]"`. Clean it up so it's just `"[XXXX]"`.
119+ return stringified . replace ( 'object ' , '' ) ;
120+ }
121+
112122 // At this point we know we either have an object or an array, we haven't seen it before, and we're going to recurse
113123 // because we haven't yet reached the max depth. Create an accumulator to hold the results of visiting each
114124 // property/entry, and keep track of the number of items we add to it.
0 commit comments