Skip to content

Commit cdda656

Browse files
committed
feat: Provide normalizeDepth option and sensible default for scope methods
1 parent 962b730 commit cdda656

File tree

6 files changed

+68
-25
lines changed

6 files changed

+68
-25
lines changed

packages/browser/src/helpers.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { captureException, withScope } from '@sentry/core';
1+
import { captureException, getCurrentHub, withScope } from '@sentry/core';
22
import { Event as SentryEvent, Mechanism, Scope, WrappedFunction } from '@sentry/types';
33
import { addExceptionMechanism, addExceptionTypeValue, normalize } from '@sentry/utils';
44

55
let ignoreOnError: number = 0;
6+
const DEFAULT_NORMALIZE_DEPTH = 3;
67

78
/**
89
* @hidden
@@ -87,6 +88,9 @@ export function wrap(
8788
} catch (ex) {
8889
ignoreNextOnError();
8990

91+
const client = getCurrentHub().getClient();
92+
const normalizeDepth = (client && client.getOptions().normalizeDepth) || DEFAULT_NORMALIZE_DEPTH;
93+
9094
withScope((scope: Scope) => {
9195
scope.addEventProcessor((event: SentryEvent) => {
9296
const processedEvent = { ...event };
@@ -98,7 +102,7 @@ export function wrap(
98102

99103
processedEvent.extra = {
100104
...processedEvent.extra,
101-
arguments: normalize(args, 3),
105+
arguments: normalize(args, normalizeDepth),
102106
};
103107

104108
return processedEvent;

packages/browser/src/integrations/breadcrumbs.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
getGlobalObject,
77
htmlTreeAsString,
88
logger,
9-
normalize,
109
parseUrl,
1110
safeJoin,
1211
} from '@sentry/utils';
@@ -75,9 +74,7 @@ export class Breadcrumbs implements Integration {
7574
const breadcrumb = {
7675
category: 'console',
7776
data: {
78-
extra: {
79-
arguments: normalize(handlerData.args, 3),
80-
},
77+
arguments: handlerData.args,
8178
logger: 'console',
8279
},
8380
level: Severity.fromString(handlerData.level),
@@ -87,7 +84,7 @@ export class Breadcrumbs implements Integration {
8784
if (handlerData.level === 'assert') {
8885
if (handlerData.args[0] === false) {
8986
breadcrumb.message = `Assertion failed: ${safeJoin(handlerData.args.slice(1), ' ') || 'console.assert'}`;
90-
breadcrumb.data.extra.arguments = normalize(handlerData.args.slice(1), 3);
87+
breadcrumb.data.arguments = handlerData.args.slice(1);
9188
} else {
9289
// Don't capture a breadcrumb for passed assertions
9390
return;

packages/hub/src/scope.ts

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ import {
1010
} from '@sentry/types';
1111
import { getGlobalObject, isThenable, normalize, SyncPromise, timestampWithMs } from '@sentry/utils';
1212

13+
import { getCurrentHub } from './hub';
14+
15+
const DEFAULT_NORMALIZE_DEPTH = 3;
16+
1317
/**
1418
* Holds additional event information. {@link Scope.applyToEvent} will be
1519
* called by the client before an event will be sent.
@@ -115,7 +119,9 @@ export class Scope implements ScopeInterface {
115119
* @inheritDoc
116120
*/
117121
public setUser(user: User | null): this {
118-
this._user = normalize(user);
122+
const client = getCurrentHub().getClient();
123+
const normalizeDepth = (client && client.getOptions().normalizeDepth) || DEFAULT_NORMALIZE_DEPTH;
124+
this._user = normalize(user, normalizeDepth);
119125
this._notifyScopeListeners();
120126
return this;
121127
}
@@ -126,7 +132,7 @@ export class Scope implements ScopeInterface {
126132
public setTags(tags: { [key: string]: string }): this {
127133
this._tags = {
128134
...this._tags,
129-
...normalize(tags),
135+
...tags,
130136
};
131137
this._notifyScopeListeners();
132138
return this;
@@ -136,19 +142,22 @@ export class Scope implements ScopeInterface {
136142
* @inheritDoc
137143
*/
138144
public setTag(key: string, value: string): this {
139-
this._tags = { ...this._tags, [key]: normalize(value) };
145+
this._tags = { ...this._tags, [key]: value };
140146
this._notifyScopeListeners();
141147
return this;
142148
}
143149

144150
/**
145151
* @inheritDoc
146152
*/
147-
public setExtras(extra: { [key: string]: any }): this {
148-
this._extra = {
149-
...this._extra,
150-
...normalize(extra),
151-
};
153+
public setExtras(extras: { [key: string]: any }): this {
154+
const client = getCurrentHub().getClient();
155+
const normalizeDepth = (client && client.getOptions().normalizeDepth) || DEFAULT_NORMALIZE_DEPTH;
156+
for (const key in extras) {
157+
if (Object.prototype.hasOwnProperty.call(extras, key)) {
158+
this._extra[key] = normalize(extras[key], normalizeDepth);
159+
}
160+
}
152161
this._notifyScopeListeners();
153162
return this;
154163
}
@@ -157,7 +166,9 @@ export class Scope implements ScopeInterface {
157166
* @inheritDoc
158167
*/
159168
public setExtra(key: string, extra: any): this {
160-
this._extra = { ...this._extra, [key]: normalize(extra) };
169+
const client = getCurrentHub().getClient();
170+
const normalizeDepth = (client && client.getOptions().normalizeDepth) || DEFAULT_NORMALIZE_DEPTH;
171+
this._extra = { ...this._extra, [key]: normalize(extra, normalizeDepth) };
161172
this._notifyScopeListeners();
162173
return this;
163174
}
@@ -166,7 +177,7 @@ export class Scope implements ScopeInterface {
166177
* @inheritDoc
167178
*/
168179
public setFingerprint(fingerprint: string[]): this {
169-
this._fingerprint = normalize(fingerprint);
180+
this._fingerprint = fingerprint;
170181
this._notifyScopeListeners();
171182
return this;
172183
}
@@ -175,7 +186,7 @@ export class Scope implements ScopeInterface {
175186
* @inheritDoc
176187
*/
177188
public setLevel(level: Severity): this {
178-
this._level = normalize(level);
189+
this._level = level;
179190
this._notifyScopeListeners();
180191
return this;
181192
}
@@ -196,7 +207,9 @@ export class Scope implements ScopeInterface {
196207
* @inheritDoc
197208
*/
198209
public setContext(name: string, context: { [key: string]: any } | null): this {
199-
this._context[name] = context ? normalize(context) : undefined;
210+
const client = getCurrentHub().getClient();
211+
const normalizeDepth = (client && client.getOptions().normalizeDepth) || DEFAULT_NORMALIZE_DEPTH;
212+
this._context[name] = context ? normalize(context, normalizeDepth) : undefined;
200213
this._notifyScopeListeners();
201214
return this;
202215
}
@@ -260,13 +273,20 @@ export class Scope implements ScopeInterface {
260273
* @inheritDoc
261274
*/
262275
public addBreadcrumb(breadcrumb: Breadcrumb, maxBreadcrumbs?: number): this {
263-
const timestamp = timestampWithMs();
264-
const mergedBreadcrumb = { timestamp, ...breadcrumb };
276+
const client = getCurrentHub().getClient();
277+
const normalizeDepth = (client && client.getOptions().normalizeDepth) || DEFAULT_NORMALIZE_DEPTH;
278+
const normalizedBreadcrumb = normalize(
279+
{
280+
timestamp: timestampWithMs(),
281+
...breadcrumb,
282+
},
283+
normalizeDepth,
284+
);
265285

266286
this._breadcrumbs =
267287
maxBreadcrumbs !== undefined && maxBreadcrumbs >= 0
268-
? [...this._breadcrumbs, normalize(mergedBreadcrumb)].slice(-maxBreadcrumbs)
269-
: [...this._breadcrumbs, normalize(mergedBreadcrumb)];
288+
? [...this._breadcrumbs, normalizedBreadcrumb].slice(-maxBreadcrumbs)
289+
: [...this._breadcrumbs, normalizedBreadcrumb];
270290
this._notifyScopeListeners();
271291
return this;
272292
}

packages/integrations/src/captureconsole.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { fill, getGlobalObject, normalize, safeJoin } from '@sentry/utils';
33

44
const global = getGlobalObject<Window | NodeJS.Global>();
55

6+
const DEFAULT_NORMALIZE_DEPTH = 3;
7+
68
/** Send Console API calls as Sentry Events */
79
export class CaptureConsole implements Integration {
810
/**
@@ -46,9 +48,12 @@ export class CaptureConsole implements Integration {
4648
const hub = getCurrentHub();
4749

4850
if (hub.getIntegration(CaptureConsole)) {
51+
const client = getCurrentHub().getClient();
52+
const normalizeDepth = (client && client.getOptions().normalizeDepth) || DEFAULT_NORMALIZE_DEPTH;
53+
4954
hub.withScope(scope => {
5055
scope.setLevel(Severity.fromString(level));
51-
scope.setExtra('arguments', normalize(args, 3));
56+
scope.setExtra('arguments', normalize(args, normalizeDepth));
5257
scope.addEventProcessor(event => {
5358
event.logger = 'console';
5459
return event;
@@ -58,7 +63,7 @@ export class CaptureConsole implements Integration {
5863
if (level === 'assert') {
5964
if (args[0] === false) {
6065
message = `Assertion failed: ${safeJoin(args.slice(1), ' ') || 'console.assert'}`;
61-
scope.setExtra('arguments', normalize(args.slice(1), 3));
66+
scope.setExtra('arguments', normalize(args.slice(1), normalizeDepth));
6267
hub.captureMessage(message);
6368
}
6469
} else {

packages/minimal/test/mocks/client.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ export class TestClient {
77
TestClient.instance = this;
88
}
99

10+
public getOptions(): object {
11+
return {};
12+
}
13+
1014
public mySecretPublicMethod(str: string): string {
1115
return `secret: ${str}`;
1216
}

packages/types/src/options.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,19 @@ export interface Options {
8787
/** Maxium number of chars a single value can have before it will be truncated. */
8888
maxValueLength?: number;
8989

90+
/**
91+
* Maxium number of levels that normalization algorithm will traverse in objects and arrays.
92+
* Used when calling one of the listed scope methods:
93+
* - `addBreadcrumb`
94+
* - `setUser`
95+
* - `setContext`
96+
* - `setExtra`
97+
* - `setExtras`.
98+
* Defaults to `3`.
99+
* See utils/object.ts::normalize() for implementation details.
100+
*/
101+
normalizeDepth?: number;
102+
90103
/**
91104
* A callback invoked during event submission, allowing to optionally modify
92105
* the event before it is sent to Sentry.

0 commit comments

Comments
 (0)