Skip to content

Commit a82d976

Browse files
fix: Revert circular replacer (#1732)
1 parent c7558a0 commit a82d976

2 files changed

Lines changed: 6 additions & 54 deletions

File tree

src/common/util/stringify.js

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,18 @@ import { ee } from '../event-emitter/contextual-ee'
77

88
/**
99
* Returns a function for use as a replacer parameter in JSON.stringify() to handle circular references.
10-
* Uses an array to track the current ancestor chain, allowing the same object to appear
11-
* multiple times in the structure as long as it's not a circular reference.
1210
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value MDN - Cyclical object value}
13-
* @returns {Function} A function that filters out circular references while allowing duplicate references.
11+
* @returns {Function} A function that filters out values it has seen before.
1412
*/
1513
const getCircularReplacer = () => {
16-
const stack = []
17-
18-
return function (key, value) {
19-
if (stack.length > 0) {
20-
// Find where we are in the stack
21-
const thisPos = stack.indexOf(this)
22-
if (~thisPos) {
23-
// We're still in the stack, trim it
24-
stack.splice(thisPos + 1)
25-
} else {
26-
// We're not in the stack, add ourselves
27-
stack.push(this)
28-
}
29-
30-
// Check if value is in the current ancestor chain
31-
if (~stack.indexOf(value)) {
14+
const seen = new WeakSet()
15+
return (key, value) => {
16+
if (typeof value === 'object' && value !== null) {
17+
if (seen.has(value)) {
3218
return
3319
}
34-
} else {
35-
// First call, initialize with root
36-
stack.push(value)
20+
seen.add(value)
3721
}
38-
3922
return value
4023
}
4124
}

tests/unit/common/util/stringify.test.js

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -42,37 +42,6 @@ test('should support serializing circular references by omitting the circular re
4242
expect(stringify(input)).toEqual('{"a":1,"arr":["foo",null]}')
4343
})
4444

45-
test('should allow the same object to appear multiple times (duplicate references) without treating it as circular', () => {
46-
// Simulates the scenario where the same "params" object is shared across multiple error events
47-
const sharedParams = {
48-
stackHash: -10208229,
49-
exceptionClass: 'Error',
50-
message: 'test error'
51-
}
52-
53-
const input = {
54-
err: [
55-
{
56-
params: sharedParams,
57-
custom: { 'source.id': 'first' },
58-
metrics: { count: 1 }
59-
},
60-
{
61-
params: sharedParams, // Same object reference, but not circular
62-
custom: { 'entity.guid': 'second' },
63-
metrics: { count: 1 }
64-
}
65-
]
66-
}
67-
68-
const result = stringify(input)
69-
const parsed = JSON.parse(result)
70-
71-
// Both err objects should have their params preserved
72-
expect(parsed.err[0].params).toEqual(sharedParams)
73-
expect(parsed.err[1].params).toEqual(sharedParams)
74-
})
75-
7645
test('should emit an "internal-error" event and still return a string if an error occurs during JSON.stringify', () => {
7746
jest.spyOn(eventEmitterModule.ee, 'emit')
7847
jest.spyOn(JSON, 'stringify').mockImplementation(() => {

0 commit comments

Comments
 (0)