Skip to content

Commit 18cc680

Browse files
author
Luca Forstner
authored
fix(utils): Normalize when serializing envelope (#5851)
1 parent 76f87f0 commit 18cc680

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

packages/utils/src/envelope.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
TextEncoderInternal,
99
} from '@sentry/types';
1010

11+
import { normalize } from './normalize';
1112
import { dropUndefinedKeys } from './object';
1213

1314
/**
@@ -67,9 +68,24 @@ export function serializeEnvelope(envelope: Envelope, textEncoder?: TextEncoderI
6768
}
6869

6970
for (const item of items) {
70-
const [itemHeaders, payload] = item as typeof items[number];
71+
const [itemHeaders, payload] = item;
72+
7173
append(`\n${JSON.stringify(itemHeaders)}\n`);
72-
append(typeof payload === 'string' || payload instanceof Uint8Array ? payload : JSON.stringify(payload));
74+
75+
if (typeof payload === 'string' || payload instanceof Uint8Array) {
76+
append(payload);
77+
} else {
78+
let stringifiedPayload: string;
79+
try {
80+
stringifiedPayload = JSON.stringify(payload);
81+
} catch (e) {
82+
// In case, despite all our efforts to keep `payload` circular-dependency-free, `JSON.strinify()` still
83+
// fails, we try again after normalizing it again with infinite normalization depth. This of course has a
84+
// performance impact but in this case a performance hit is better than throwing.
85+
stringifiedPayload = JSON.stringify(normalize(payload));
86+
}
87+
append(stringifiedPayload);
88+
}
7389
}
7490

7591
return typeof parts === 'string' ? parts : concatBuffers(parts);

packages/utils/test/envelope.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,21 @@ describe('envelope', () => {
5858
Uint8Array.from([7, 8, 9, 10, 11, 12]),
5959
]);
6060
});
61+
62+
it("doesn't throw when being passed a an envelope that contains a circular item payload", () => {
63+
const chicken: { egg?: unknown } = {};
64+
const egg = { chicken };
65+
chicken.egg = chicken;
66+
67+
const env = createEnvelope<EventEnvelope>({ event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2', sent_at: '123' }, [
68+
[{ type: 'event' }, egg],
69+
]);
70+
71+
const serializedEnvelope = serializeEnvelope(env, new TextEncoder());
72+
const [, , serializedBody] = serializedEnvelope.toString().split('\n');
73+
74+
expect(serializedBody).toBe('{"chicken":{"egg":"[Circular ~]"}}');
75+
});
6176
});
6277

6378
describe('addItemToEnvelope()', () => {

0 commit comments

Comments
 (0)