Skip to content

Commit 14a10dc

Browse files
committed
make generic across all javascript
1 parent 52047b6 commit 14a10dc

File tree

14 files changed

+110
-68
lines changed

14 files changed

+110
-68
lines changed

packages/browser/src/backend.ts

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { BaseBackend, getEnvelopeEndpointWithUrlEncodedAuth, initAPIDetails } from '@sentry/core';
22
import { Event, EventHint, Options, Severity, Transport, TransportOptions } from '@sentry/types';
3-
import { StackLineParser, StackParser, stackParserFromOptions, supportsFetch } from '@sentry/utils';
3+
import { stackParserFromOptions, supportsFetch } from '@sentry/utils';
44

55
import { eventFromException, eventFromMessage } from './eventbuilder';
66
import { FetchTransport, makeNewFetchTransport, makeNewXHRTransport, XHRTransport } from './transports';
@@ -23,12 +23,6 @@ export interface BrowserOptions extends Options {
2323
* By default, all errors will be sent.
2424
*/
2525
denyUrls?: Array<string | RegExp>;
26-
27-
/**
28-
* A stack parser implementation or an array of stack line parsers
29-
* By default, a stack parser is supplied for all supported browsers
30-
*/
31-
stackParser?: StackParser | StackLineParser[];
3226
}
3327

3428
/**

packages/node/src/backend.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { BaseBackend, getEnvelopeEndpointWithUrlEncodedAuth, initAPIDetails } from '@sentry/core';
22
import { Event, EventHint, Severity, Transport, TransportOptions } from '@sentry/types';
3-
import { makeDsn, resolvedSyncPromise } from '@sentry/utils';
3+
import { makeDsn, resolvedSyncPromise, stackParserFromOptions } from '@sentry/utils';
44

55
import { eventFromMessage, eventFromUnknownInput } from './eventbuilder';
66
import { HTTPSTransport, HTTPTransport, makeNodeTransport } from './transports';
@@ -16,14 +16,16 @@ export class NodeBackend extends BaseBackend<NodeOptions> {
1616
*/
1717
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
1818
public eventFromException(exception: any, hint?: EventHint): PromiseLike<Event> {
19-
return resolvedSyncPromise(eventFromUnknownInput(exception, hint));
19+
return resolvedSyncPromise(eventFromUnknownInput(stackParserFromOptions(this._options), exception, hint));
2020
}
2121

2222
/**
2323
* @inheritDoc
2424
*/
2525
public eventFromMessage(message: string, level: Severity = Severity.Info, hint?: EventHint): PromiseLike<Event> {
26-
return resolvedSyncPromise(eventFromMessage(message, level, hint, this._options.attachStacktrace));
26+
return resolvedSyncPromise(
27+
eventFromMessage(stackParserFromOptions(this._options), message, level, hint, this._options.attachStacktrace),
28+
);
2729
}
2830

2931
/**

packages/node/src/eventbuilder.ts

+9-11
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,31 @@
11
import { getCurrentHub } from '@sentry/hub';
2-
import { Event, EventHint, Exception, Mechanism, Severity, StackFrame } from '@sentry/types';
2+
import { Event, EventHint, Exception, Mechanism, Severity, StackFrame, StackParser } from '@sentry/types';
33
import {
44
addExceptionMechanism,
55
addExceptionTypeValue,
6-
createStackParser,
76
extractExceptionKeysForMessage,
87
isError,
98
isPlainObject,
109
normalizeToSize,
1110
} from '@sentry/utils';
1211

13-
import { nodeStackParser } from './stack-parser';
14-
1512
/**
1613
* Extracts stack frames from the error.stack string
1714
*/
18-
export function parseStackFrames(error: Error): StackFrame[] {
19-
return createStackParser(nodeStackParser)(error.stack || '', 1);
15+
export function parseStackFrames(stackParser: StackParser, error: Error): StackFrame[] {
16+
return stackParser(error.stack || '', 1);
2017
}
2118

2219
/**
2320
* Extracts stack frames from the error and builds a Sentry Exception
2421
*/
25-
export function exceptionFromError(error: Error): Exception {
22+
export function exceptionFromError(stackParser: StackParser, error: Error): Exception {
2623
const exception: Exception = {
2724
type: error.name || error.constructor.name,
2825
value: error.message,
2926
};
3027

31-
const frames = parseStackFrames(error);
28+
const frames = parseStackFrames(stackParser, error);
3229
if (frames.length) {
3330
exception.stacktrace = { frames };
3431
}
@@ -40,7 +37,7 @@ export function exceptionFromError(error: Error): Exception {
4037
* Builds and Event from a Exception
4138
* @hidden
4239
*/
43-
export function eventFromUnknownInput(exception: unknown, hint?: EventHint): Event {
40+
export function eventFromUnknownInput(stackParser: StackParser, exception: unknown, hint?: EventHint): Event {
4441
// eslint-disable-next-line @typescript-eslint/no-explicit-any
4542
let ex: unknown = exception;
4643
const providedMechanism: Mechanism | undefined =
@@ -73,7 +70,7 @@ export function eventFromUnknownInput(exception: unknown, hint?: EventHint): Eve
7370

7471
const event = {
7572
exception: {
76-
values: [exceptionFromError(ex as Error)],
73+
values: [exceptionFromError(stackParser, ex as Error)],
7774
},
7875
};
7976

@@ -91,6 +88,7 @@ export function eventFromUnknownInput(exception: unknown, hint?: EventHint): Eve
9188
* @hidden
9289
*/
9390
export function eventFromMessage(
91+
stackParser: StackParser,
9492
message: string,
9593
level: Severity = Severity.Info,
9694
hint?: EventHint,
@@ -103,7 +101,7 @@ export function eventFromMessage(
103101
};
104102

105103
if (attachStacktrace && hint && hint.syntheticException) {
106-
const frames = parseStackFrames(hint.syntheticException);
104+
const frames = parseStackFrames(stackParser, hint.syntheticException);
107105
if (frames.length) {
108106
event.stacktrace = { frames };
109107
}

packages/node/src/integrations/linkederrors.ts

+20-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { addGlobalEventProcessor, getCurrentHub } from '@sentry/core';
2-
import { Event, EventHint, Exception, ExtendedError, Integration } from '@sentry/types';
3-
import { isInstanceOf, resolvedSyncPromise, SyncPromise } from '@sentry/utils';
2+
import { Event, EventHint, Exception, ExtendedError, Integration, StackParser } from '@sentry/types';
3+
import { isInstanceOf, resolvedSyncPromise, stackParserFromOptions, SyncPromise } from '@sentry/utils';
44

5+
import { NodeClient } from '../client';
56
import { exceptionFromError } from '../eventbuilder';
67
import { ContextLines } from './contextlines';
78

@@ -42,26 +43,29 @@ export class LinkedErrors implements Integration {
4243
* @inheritDoc
4344
*/
4445
public setupOnce(): void {
45-
addGlobalEventProcessor((event: Event, hint?: EventHint) => {
46-
const self = getCurrentHub().getIntegration(LinkedErrors);
46+
addGlobalEventProcessor(async (event: Event, hint?: EventHint) => {
47+
const hub = getCurrentHub();
48+
const self = hub.getIntegration(LinkedErrors);
49+
const stackParser = stackParserFromOptions(hub.getClient<NodeClient>()?.getOptions());
50+
4751
if (self) {
48-
const handler = self._handler && self._handler.bind(self);
49-
return typeof handler === 'function' ? handler(event, hint) : event;
52+
await self._handler(stackParser, event, hint);
5053
}
54+
5155
return event;
5256
});
5357
}
5458

5559
/**
5660
* @inheritDoc
5761
*/
58-
private _handler(event: Event, hint?: EventHint): PromiseLike<Event> {
62+
private _handler(stackParser: StackParser, event: Event, hint?: EventHint): PromiseLike<Event> {
5963
if (!event.exception || !event.exception.values || !hint || !isInstanceOf(hint.originalException, Error)) {
6064
return resolvedSyncPromise(event);
6165
}
6266

6367
return new SyncPromise<Event>(resolve => {
64-
void this._walkErrorTree(hint.originalException as Error, this._key)
68+
void this._walkErrorTree(stackParser, hint.originalException as Error, this._key)
6569
.then((linkedErrors: Exception[]) => {
6670
if (event && event.exception && event.exception.values) {
6771
event.exception.values = [...linkedErrors, ...event.exception.values];
@@ -77,12 +81,17 @@ export class LinkedErrors implements Integration {
7781
/**
7882
* @inheritDoc
7983
*/
80-
private async _walkErrorTree(error: ExtendedError, key: string, stack: Exception[] = []): Promise<Exception[]> {
84+
private async _walkErrorTree(
85+
stackParser: StackParser,
86+
error: ExtendedError,
87+
key: string,
88+
stack: Exception[] = [],
89+
): Promise<Exception[]> {
8190
if (!isInstanceOf(error[key], Error) || stack.length + 1 >= this._limit) {
8291
return Promise.resolve(stack);
8392
}
8493

85-
const exception = exceptionFromError(error[key]);
94+
const exception = exceptionFromError(stackParser, error[key]);
8695

8796
// If the ContextLines integration is enabled, we add source code context to linked errors
8897
// because we can't guarantee the order that integrations are run.
@@ -92,7 +101,7 @@ export class LinkedErrors implements Integration {
92101
}
93102

94103
return new Promise<Exception[]>((resolve, reject) => {
95-
void this._walkErrorTree(error[key], key, [exception, ...stack])
104+
void this._walkErrorTree(stackParser, error[key], key, [exception, ...stack])
96105
.then(resolve)
97106
.then(null, () => {
98107
reject();

packages/node/src/sdk.ts

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import * as domain from 'domain';
77
import { NodeClient } from './client';
88
import { IS_DEBUG_BUILD } from './flags';
99
import { Console, ContextLines, Http, LinkedErrors, OnUncaughtException, OnUnhandledRejection } from './integrations';
10+
import { nodeStackParser } from './stack-parser';
1011
import { NodeOptions } from './types';
1112

1213
export const defaultIntegrations = [
@@ -120,6 +121,10 @@ export function init(options: NodeOptions = {}): void {
120121
options.autoSessionTracking = true;
121122
}
122123

124+
if (options.stackParser === undefined) {
125+
options.stackParser = [nodeStackParser];
126+
}
127+
123128
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
124129
if ((domain as any).active) {
125130
setHubOnCarrier(carrier, getCurrentHub());

packages/node/src/stack-parser.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { basename, dirname, StackLineParser, StackLineParserFn } from '@sentry/utils';
1+
import { StackLineParser, StackLineParserFn } from '@sentry/types';
2+
import { basename, dirname } from '@sentry/utils';
23

34
/** Gets the module */
45
function getModule(filename: string | undefined): string | undefined {

packages/node/test/context-lines.test.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import { StackFrame } from '@sentry/types';
2+
import { createStackParser } from '@sentry/utils';
23
import * as fs from 'fs';
34

45
import { parseStackFrames } from '../src/eventbuilder';
56
import { ContextLines, resetFileContentCache } from '../src/integrations/contextlines';
7+
import { nodeStackParser } from '../src/stack-parser';
68
import { getError } from './helper/error';
79

10+
const parser = createStackParser(nodeStackParser);
11+
812
describe('ContextLines', () => {
913
let readFileSpy: jest.SpyInstance;
1014
let contextLines: ContextLines;
@@ -27,7 +31,7 @@ describe('ContextLines', () => {
2731
test('parseStack with same file', async () => {
2832
expect.assertions(1);
2933

30-
const frames = parseStackFrames(new Error('test'));
34+
const frames = parseStackFrames(parser, new Error('test'));
3135

3236
await addContext(Array.from(frames));
3337

@@ -57,12 +61,12 @@ describe('ContextLines', () => {
5761

5862
test('parseStack with adding different file', async () => {
5963
expect.assertions(1);
60-
const frames = parseStackFrames(new Error('test'));
64+
const frames = parseStackFrames(parser, new Error('test'));
6165

6266
await addContext(frames);
6367

6468
const numCalls = readFileSpy.mock.calls.length;
65-
const parsedFrames = parseStackFrames(getError());
69+
const parsedFrames = parseStackFrames(parser, getError());
6670
await addContext(parsedFrames);
6771

6872
const newErrorCalls = readFileSpy.mock.calls.length;
@@ -100,7 +104,7 @@ describe('ContextLines', () => {
100104
contextLines = new ContextLines({ frameContextLines: 0 });
101105

102106
expect.assertions(1);
103-
const frames = parseStackFrames(new Error('test'));
107+
const frames = parseStackFrames(parser, new Error('test'));
104108

105109
await addContext(frames);
106110
expect(readFileSpy).toHaveBeenCalledTimes(0);

packages/node/test/index.test.ts

+13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { initAndBind, SDK_VERSION } from '@sentry/core';
22
import { getMainCarrier } from '@sentry/hub';
33
import { Integration } from '@sentry/types';
4+
import { createStackParser } from '@sentry/utils';
45
import * as domain from 'domain';
56

67
import {
@@ -17,6 +18,9 @@ import {
1718
} from '../src';
1819
import { NodeBackend } from '../src/backend';
1920
import { ContextLines, LinkedErrors } from '../src/integrations';
21+
import { nodeStackParser } from '../src/stack-parser';
22+
23+
const stackParser = createStackParser(nodeStackParser);
2024

2125
jest.mock('@sentry/core', () => {
2226
const original = jest.requireActual('@sentry/core');
@@ -87,6 +91,7 @@ describe('SentryNode', () => {
8791

8892
test('record auto breadcrumbs', done => {
8993
const client = new NodeClient({
94+
stackParser,
9095
beforeSend: (event: Event) => {
9196
// TODO: It should be 3, but we don't capture a breadcrumb
9297
// for our own captureMessage/captureException calls yet
@@ -118,6 +123,7 @@ describe('SentryNode', () => {
118123
expect.assertions(6);
119124
getCurrentHub().bindClient(
120125
new NodeClient({
126+
stackParser,
121127
beforeSend: (event: Event) => {
122128
expect(event.tags).toEqual({ test: '1' });
123129
expect(event.exception).not.toBeUndefined();
@@ -145,6 +151,7 @@ describe('SentryNode', () => {
145151
expect.assertions(6);
146152
getCurrentHub().bindClient(
147153
new NodeClient({
154+
stackParser,
148155
beforeSend: (event: Event) => {
149156
expect(event.tags).toEqual({ test: '1' });
150157
expect(event.exception).not.toBeUndefined();
@@ -172,6 +179,7 @@ describe('SentryNode', () => {
172179
expect.assertions(10);
173180
getCurrentHub().bindClient(
174181
new NodeClient({
182+
stackParser,
175183
beforeSend: (event: Event) => {
176184
expect(event.tags).toEqual({ test: '1' });
177185
expect(event.exception).not.toBeUndefined();
@@ -203,6 +211,7 @@ describe('SentryNode', () => {
203211
expect.assertions(15);
204212
getCurrentHub().bindClient(
205213
new NodeClient({
214+
stackParser,
206215
integrations: [new ContextLines(), new LinkedErrors()],
207216
beforeSend: (event: Event) => {
208217
expect(event.exception).not.toBeUndefined();
@@ -243,6 +252,7 @@ describe('SentryNode', () => {
243252
expect.assertions(2);
244253
getCurrentHub().bindClient(
245254
new NodeClient({
255+
stackParser,
246256
beforeSend: (event: Event) => {
247257
expect(event.message).toBe('test');
248258
expect(event.exception).toBeUndefined();
@@ -259,6 +269,7 @@ describe('SentryNode', () => {
259269
expect.assertions(2);
260270
getCurrentHub().bindClient(
261271
new NodeClient({
272+
stackParser,
262273
beforeSend: (event: Event) => {
263274
expect(event.message).toBe('test event');
264275
expect(event.exception).toBeUndefined();
@@ -275,6 +286,7 @@ describe('SentryNode', () => {
275286
const d = domain.create();
276287

277288
const client = new NodeClient({
289+
stackParser,
278290
beforeSend: (event: Event) => {
279291
expect(event.message).toBe('test domain');
280292
expect(event.exception).toBeUndefined();
@@ -295,6 +307,7 @@ describe('SentryNode', () => {
295307
expect.assertions(1);
296308
getCurrentHub().bindClient(
297309
new NodeClient({
310+
stackParser,
298311
beforeSend: (event: Event) => {
299312
expect(
300313
event.exception!.values![0].stacktrace!.frames![

0 commit comments

Comments
 (0)