Skip to content

Commit

Permalink
fix(core): Use maxValueLength in extra error data integration (#12174)
Browse files Browse the repository at this point in the history
fixes #12168

We should truncate extra error data keys using `maxValueLength` to make
sure event payload size stays reasonably small.
  • Loading branch information
AbhiPrasad authored Jun 19, 2024
1 parent 1d66b8a commit 2fbd7cc
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 18 deletions.
18 changes: 12 additions & 6 deletions packages/core/src/integrations/extraerrordata.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Contexts, Event, EventHint, ExtendedError, IntegrationFn } from '@sentry/types';
import { addNonEnumerableProperty, isError, isPlainObject, logger, normalize } from '@sentry/utils';
import { addNonEnumerableProperty, isError, isPlainObject, logger, normalize, truncate } from '@sentry/utils';
import { defineIntegration } from '../integration';

import { DEBUG_BUILD } from '../debug-build';
Expand Down Expand Up @@ -27,8 +27,9 @@ const _extraErrorDataIntegration = ((options: Partial<ExtraErrorDataOptions> = {
const { depth = 3, captureErrorCause = true } = options;
return {
name: INTEGRATION_NAME,
processEvent(event, hint) {
return _enhanceEventWithErrorData(event, hint, depth, captureErrorCause);
processEvent(event, hint, client) {
const { maxValueLength = 250 } = client.getOptions();
return _enhanceEventWithErrorData(event, hint, depth, captureErrorCause, maxValueLength);
},
};
}) satisfies IntegrationFn;
Expand All @@ -40,13 +41,14 @@ function _enhanceEventWithErrorData(
hint: EventHint = {},
depth: number,
captureErrorCause: boolean,
maxValueLength: number,
): Event {
if (!hint.originalException || !isError(hint.originalException)) {
return event;
}
const exceptionName = (hint.originalException as ExtendedError).name || hint.originalException.constructor.name;

const errorData = _extractErrorData(hint.originalException as ExtendedError, captureErrorCause);
const errorData = _extractErrorData(hint.originalException as ExtendedError, captureErrorCause, maxValueLength);

if (errorData) {
const contexts: Contexts = {
Expand Down Expand Up @@ -74,7 +76,11 @@ function _enhanceEventWithErrorData(
/**
* Extract extra information from the Error object
*/
function _extractErrorData(error: ExtendedError, captureErrorCause: boolean): Record<string, unknown> | null {
function _extractErrorData(
error: ExtendedError,
captureErrorCause: boolean,
maxValueLength: number,
): Record<string, unknown> | null {
// We are trying to enhance already existing event, so no harm done if it won't succeed
try {
const nativeKeys = [
Expand All @@ -97,7 +103,7 @@ function _extractErrorData(error: ExtendedError, captureErrorCause: boolean): Re
continue;
}
const value = error[key];
extraErrorInfo[key] = isError(value) ? value.toString() : value;
extraErrorInfo[key] = isError(value) || typeof value === 'string' ? truncate(`${value}`, maxValueLength) : value;
}

// Error.cause is a standard property that is non enumerable, we therefore need to access it separately.
Expand Down
48 changes: 36 additions & 12 deletions packages/core/test/lib/integrations/extraerrordata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ import type { Event as SentryEvent, ExtendedError } from '@sentry/types';

import { extraErrorDataIntegration } from '../../../src/integrations/extraerrordata';

import { TestClient, getDefaultTestClientOptions } from '../../mocks/client';

const extraErrorData = extraErrorDataIntegration();
let event: SentryEvent;

describe('ExtraErrorData()', () => {
const testClient = new TestClient(getDefaultTestClientOptions({ maxValueLength: 250 }));
beforeEach(() => {
event = {};
});
Expand All @@ -20,7 +23,7 @@ describe('ExtraErrorData()', () => {
{
originalException: error,
},
{} as any,
testClient,
) as SentryEvent;

expect(enhancedEvent.contexts).toEqual({
Expand All @@ -31,6 +34,27 @@ describe('ExtraErrorData()', () => {
});
});

it('should use maxValueLength to truncate extra data', () => {
const error = new TypeError('foo') as ExtendedError;
error.baz = 42;
error.foo = 'a'.repeat(300);

const enhancedEvent = extraErrorData.processEvent?.(
event,
{
originalException: error,
},
testClient,
) as SentryEvent;

expect(enhancedEvent.contexts).toEqual({
TypeError: {
baz: 42,
foo: `${'a'.repeat(250)}...`,
},
});
});

it('doesnt choke on linked errors and stringify names instead', () => {
const error = new TypeError('foo') as ExtendedError;
error.cause = new SyntaxError('bar');
Expand All @@ -40,7 +64,7 @@ describe('ExtraErrorData()', () => {
{
originalException: error,
},
{} as any,
testClient,
) as SentryEvent;

expect(enhancedEvent.contexts).toEqual({
Expand All @@ -65,7 +89,7 @@ describe('ExtraErrorData()', () => {
{
originalException: error,
},
{} as any,
testClient,
) as SentryEvent;

expect(enhancedEvent.contexts).toEqual({
Expand Down Expand Up @@ -93,7 +117,7 @@ describe('ExtraErrorData()', () => {
{
originalException: error,
},
{} as any,
testClient,
) as SentryEvent;

expect(enhancedEvent.contexts).toEqual({
Expand All @@ -112,14 +136,14 @@ describe('ExtraErrorData()', () => {
{
originalException: error,
},
{} as any,
testClient,
) as SentryEvent;

expect(enhancedEvent).toEqual(event);
});

it('should return event if there is no SentryEventHint', () => {
const enhancedEvent = extraErrorData.processEvent?.(event, {}, {} as any);
const enhancedEvent = extraErrorData.processEvent?.(event, {}, testClient);

expect(enhancedEvent).toEqual(event);
});
Expand All @@ -131,7 +155,7 @@ describe('ExtraErrorData()', () => {
// @ts-expect-error Allow event to have extra properties
notOriginalException: 'fooled you',
},
{} as any,
testClient,
);

expect(enhancedEvent).toEqual(event);
Expand All @@ -153,7 +177,7 @@ describe('ExtraErrorData()', () => {
{
originalException: error,
},
{} as any,
testClient,
) as SentryEvent;

expect(enhancedEvent.contexts).toEqual({
Expand All @@ -180,7 +204,7 @@ describe('ExtraErrorData()', () => {
{
originalException: error,
},
{} as any,
testClient,
) as SentryEvent;

expect(enhancedEvent.contexts).toEqual({
Expand All @@ -204,7 +228,7 @@ describe('ExtraErrorData()', () => {
{
originalException: error,
},
{} as any,
testClient,
) as SentryEvent;

expect(enhancedEvent.contexts).toEqual({
Expand Down Expand Up @@ -232,7 +256,7 @@ describe('ExtraErrorData()', () => {
{
originalException: error,
},
{} as any,
testClient,
) as SentryEvent;

expect(enhancedEvent.contexts).toEqual({
Expand Down Expand Up @@ -261,7 +285,7 @@ describe('ExtraErrorData()', () => {
{
originalException: error,
},
{} as any,
testClient,
) as SentryEvent;

expect(enhancedEvent.contexts).not.toEqual({
Expand Down

0 comments on commit 2fbd7cc

Please sign in to comment.