Skip to content

Commit 08818d8

Browse files
authored
fix(tracing): Filter out invalid resource sizes (#9641)
There's a bug in some browsers that attaches huge resource sizes that are completely unrealistic. Here's an example in chromium: https://bugs.chromium.org/p/chromium/issues/detail?id=1324812#c25 To get around this, we add a filter to enforce that resource sizes should only be attached if the size is < 2147483647 bytes (size of maximum value of integer in c/c++).
1 parent 2787643 commit 08818d8

File tree

2 files changed

+37
-9
lines changed

2 files changed

+37
-9
lines changed

packages/tracing-internal/src/browser/metrics/index.ts

+17-9
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import { getVisibilityWatcher } from '../web-vitals/lib/getVisibilityWatcher';
1515
import type { NavigatorDeviceMemory, NavigatorNetworkInformation } from '../web-vitals/types';
1616
import { _startChild, isMeasurementValue } from './utils';
1717

18+
const MAX_INT_AS_BYTES = 2147483647;
19+
1820
/**
1921
* Converts from milliseconds to seconds
2022
* @param time time in ms
@@ -402,15 +404,9 @@ export function _addResourceSpans(
402404

403405
// eslint-disable-next-line @typescript-eslint/no-explicit-any
404406
const data: Record<string, any> = {};
405-
if ('transferSize' in entry) {
406-
data['http.response_transfer_size'] = entry.transferSize;
407-
}
408-
if ('encodedBodySize' in entry) {
409-
data['http.response_content_length'] = entry.encodedBodySize;
410-
}
411-
if ('decodedBodySize' in entry) {
412-
data['http.decoded_response_content_length'] = entry.decodedBodySize;
413-
}
407+
setResourceEntrySizeData(data, entry, 'transferSize', 'http.response_transfer_size');
408+
setResourceEntrySizeData(data, entry, 'encodedBodySize', 'http.response_content_length');
409+
setResourceEntrySizeData(data, entry, 'decodedBodySize', 'http.decoded_response_content_length');
414410
if ('renderBlockingStatus' in entry) {
415411
data['resource.render_blocking_status'] = entry.renderBlockingStatus;
416412
}
@@ -493,3 +489,15 @@ function _tagMetricInfo(transaction: Transaction): void {
493489
);
494490
}
495491
}
492+
493+
function setResourceEntrySizeData(
494+
data: Record<string, unknown>,
495+
entry: ResourceEntry,
496+
key: keyof Pick<ResourceEntry, 'transferSize' | 'encodedBodySize' | 'decodedBodySize'>,
497+
dataKey: 'http.response_transfer_size' | 'http.response_content_length' | 'http.decoded_response_content_length',
498+
): void {
499+
const entryVal = entry[key];
500+
if (entryVal !== undefined && entryVal < MAX_INT_AS_BYTES) {
501+
data[dataKey] = entryVal;
502+
}
503+
}

packages/tracing-internal/test/browser/metrics/index.test.ts

+20
Original file line numberDiff line numberDiff line change
@@ -169,4 +169,24 @@ describe('_addResourceSpans', () => {
169169
}),
170170
);
171171
});
172+
173+
it('does not attach resource sizes that exceed MAX_INT bytes', () => {
174+
const entry: ResourceEntry = {
175+
initiatorType: 'css',
176+
transferSize: 2147483647,
177+
encodedBodySize: 2147483647,
178+
decodedBodySize: 2147483647,
179+
};
180+
181+
_addResourceSpans(transaction, entry, '/assets/to/css', 100, 23, 345);
182+
183+
// eslint-disable-next-line @typescript-eslint/unbound-method
184+
expect(transaction.startChild).toHaveBeenCalledTimes(1);
185+
// eslint-disable-next-line @typescript-eslint/unbound-method
186+
expect(transaction.startChild).toHaveBeenLastCalledWith(
187+
expect.objectContaining({
188+
data: {},
189+
}),
190+
);
191+
});
172192
});

0 commit comments

Comments
 (0)