Skip to content

Commit 1c3f85a

Browse files
authored
ref(node): Extract backend logic into eventbuilders (#4337)
To make the diff easier to read when we remove the backend, I cherry-picked this patch that extracts the `eventFromException` and `eventFromMessage` logic from the backend into their own functions into this PR. This patch updates node eventbuilders to have the same structure as browser. This will help when we remove the backend as we can apply this same strategies for migrating off the backend.
1 parent 1afabcd commit 1c3f85a

File tree

2 files changed

+104
-79
lines changed

2 files changed

+104
-79
lines changed

packages/node/src/backend.ts

Lines changed: 6 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,8 @@
1-
import { BaseBackend, getCurrentHub } from '@sentry/core';
2-
import { Event, EventHint, Mechanism, SeverityLevel, Transport, TransportOptions } from '@sentry/types';
3-
import {
4-
addExceptionMechanism,
5-
addExceptionTypeValue,
6-
Dsn,
7-
extractExceptionKeysForMessage,
8-
isError,
9-
isPlainObject,
10-
normalizeToSize,
11-
SyncPromise,
12-
} from '@sentry/utils';
1+
import { BaseBackend } from '@sentry/core';
2+
import { Event, EventHint, SeverityLevel, Transport, TransportOptions } from '@sentry/types';
3+
import { Dsn } from '@sentry/utils';
134

14-
import { extractStackFromError, parseError, parseStack, prepareFramesForEvent } from './parsers';
5+
import { eventFromException, eventFromMessage } from './eventbuilder';
156
import { HTTPSTransport, HTTPTransport } from './transports';
167
import { NodeOptions } from './types';
178

@@ -25,78 +16,14 @@ export class NodeBackend extends BaseBackend<NodeOptions> {
2516
*/
2617
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
2718
public eventFromException(exception: any, hint?: EventHint): PromiseLike<Event> {
28-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
29-
let ex: any = exception;
30-
const providedMechanism: Mechanism | undefined =
31-
hint && hint.data && (hint.data as { mechanism: Mechanism }).mechanism;
32-
const mechanism: Mechanism = providedMechanism || {
33-
handled: true,
34-
type: 'generic',
35-
};
36-
37-
if (!isError(exception)) {
38-
if (isPlainObject(exception)) {
39-
// This will allow us to group events based on top-level keys
40-
// which is much better than creating new group when any key/value change
41-
const message = `Non-Error exception captured with keys: ${extractExceptionKeysForMessage(exception)}`;
42-
43-
getCurrentHub().configureScope(scope => {
44-
scope.setExtra('__serialized__', normalizeToSize(exception as Record<string, unknown>));
45-
});
46-
47-
ex = (hint && hint.syntheticException) || new Error(message);
48-
(ex as Error).message = message;
49-
} else {
50-
// This handles when someone does: `throw "something awesome";`
51-
// We use synthesized Error here so we can extract a (rough) stack trace.
52-
ex = (hint && hint.syntheticException) || new Error(exception as string);
53-
(ex as Error).message = exception;
54-
}
55-
mechanism.synthetic = true;
56-
}
57-
58-
return new SyncPromise<Event>((resolve, reject) =>
59-
parseError(ex as Error, this._options)
60-
.then(event => {
61-
addExceptionTypeValue(event, undefined, undefined);
62-
addExceptionMechanism(event, mechanism);
63-
64-
resolve({
65-
...event,
66-
event_id: hint && hint.event_id,
67-
});
68-
})
69-
.then(null, reject),
70-
);
19+
return eventFromException(this._options, exception, hint);
7120
}
7221

7322
/**
7423
* @inheritDoc
7524
*/
7625
public eventFromMessage(message: string, level: SeverityLevel = 'info', hint?: EventHint): PromiseLike<Event> {
77-
const event: Event = {
78-
event_id: hint && hint.event_id,
79-
level,
80-
message,
81-
};
82-
83-
return new SyncPromise<Event>(resolve => {
84-
if (this._options.attachStacktrace && hint && hint.syntheticException) {
85-
const stack = hint.syntheticException ? extractStackFromError(hint.syntheticException) : [];
86-
void parseStack(stack, this._options)
87-
.then(frames => {
88-
event.stacktrace = {
89-
frames: prepareFramesForEvent(frames),
90-
};
91-
resolve(event);
92-
})
93-
.then(null, () => {
94-
resolve(event);
95-
});
96-
} else {
97-
resolve(event);
98-
}
99-
});
26+
return eventFromMessage(this._options, message, level, hint);
10027
}
10128

10229
/**

packages/node/src/eventbuilder.ts

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { getCurrentHub } from '@sentry/hub';
2+
import { Event, EventHint, Mechanism, Options, SeverityLevel } from '@sentry/types';
3+
import {
4+
addExceptionMechanism,
5+
addExceptionTypeValue,
6+
extractExceptionKeysForMessage,
7+
isError,
8+
isPlainObject,
9+
normalizeToSize,
10+
SyncPromise,
11+
} from '@sentry/utils';
12+
13+
import { extractStackFromError, parseError, parseStack, prepareFramesForEvent } from './parsers';
14+
15+
/**
16+
* Builds and Event from a Exception
17+
* @hidden
18+
*/
19+
export function eventFromException(options: Options, exception: unknown, hint?: EventHint): PromiseLike<Event> {
20+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
21+
let ex: any = exception;
22+
const providedMechanism: Mechanism | undefined =
23+
hint && hint.data && (hint.data as { mechanism: Mechanism }).mechanism;
24+
const mechanism: Mechanism = providedMechanism || {
25+
handled: true,
26+
type: 'generic',
27+
};
28+
29+
if (!isError(exception)) {
30+
if (isPlainObject(exception)) {
31+
// This will allow us to group events based on top-level keys
32+
// which is much better than creating new group when any key/value change
33+
const message = `Non-Error exception captured with keys: ${extractExceptionKeysForMessage(exception)}`;
34+
35+
getCurrentHub().configureScope(scope => {
36+
scope.setExtra('__serialized__', normalizeToSize(exception as Record<string, unknown>));
37+
});
38+
39+
ex = (hint && hint.syntheticException) || new Error(message);
40+
(ex as Error).message = message;
41+
} else {
42+
// This handles when someone does: `throw "something awesome";`
43+
// We use synthesized Error here so we can extract a (rough) stack trace.
44+
ex = (hint && hint.syntheticException) || new Error(exception as string);
45+
(ex as Error).message = exception as string;
46+
}
47+
mechanism.synthetic = true;
48+
}
49+
50+
return new SyncPromise<Event>((resolve, reject) =>
51+
parseError(ex as Error, options)
52+
.then(event => {
53+
addExceptionTypeValue(event, undefined, undefined);
54+
addExceptionMechanism(event, mechanism);
55+
56+
resolve({
57+
...event,
58+
event_id: hint && hint.event_id,
59+
});
60+
})
61+
.then(null, reject),
62+
);
63+
}
64+
65+
/**
66+
* Builds and Event from a Message
67+
* @hidden
68+
*/
69+
export function eventFromMessage(
70+
options: Options,
71+
message: string,
72+
level: SeverityLevel = 'info',
73+
hint?: EventHint,
74+
): PromiseLike<Event> {
75+
const event: Event = {
76+
event_id: hint && hint.event_id,
77+
level,
78+
message,
79+
};
80+
81+
return new SyncPromise<Event>(resolve => {
82+
if (options.attachStacktrace && hint && hint.syntheticException) {
83+
const stack = hint.syntheticException ? extractStackFromError(hint.syntheticException) : [];
84+
void parseStack(stack, options)
85+
.then(frames => {
86+
event.stacktrace = {
87+
frames: prepareFramesForEvent(frames),
88+
};
89+
resolve(event);
90+
})
91+
.then(null, () => {
92+
resolve(event);
93+
});
94+
} else {
95+
resolve(event);
96+
}
97+
});
98+
}

0 commit comments

Comments
 (0)