Skip to content

Commit 4a4366d

Browse files
authored
feat(node): Improve non-error messages (#9026)
1 parent 042e7ce commit 4a4366d

File tree

4 files changed

+58
-9
lines changed

4 files changed

+58
-9
lines changed

packages/node-integration-tests/suites/public-api/captureException/empty-obj/test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ test('should capture an empty object', async () => {
99
values: [
1010
{
1111
type: 'Error',
12-
value: 'Non-Error exception captured with keys: [object has no keys]',
12+
value: 'Object captured as exception with keys: [object has no keys]',
1313
mechanism: {
1414
type: 'generic',
1515
handled: true,

packages/remix/test/integration/test/server/action.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -304,8 +304,8 @@ describe.each(['builtin', 'express'])('Remix API Actions with adapter = %s', ada
304304
{
305305
type: 'Error',
306306
value: useV2
307-
? 'Non-Error exception captured with keys: data, internal, status, statusText'
308-
: 'Non-Error exception captured with keys: data',
307+
? 'Object captured as exception with keys: data, internal, status, statusText'
308+
: 'Object captured as exception with keys: data',
309309
stacktrace: expect.any(Object),
310310
mechanism: {
311311
data: {
@@ -412,8 +412,8 @@ describe.each(['builtin', 'express'])('Remix API Actions with adapter = %s', ada
412412
{
413413
type: 'Error',
414414
value: useV2
415-
? 'Non-Error exception captured with keys: data, internal, status, statusText'
416-
: 'Non-Error exception captured with keys: [object has no keys]',
415+
? 'Object captured as exception with keys: data, internal, status, statusText'
416+
: 'Object captured as exception with keys: [object has no keys]',
417417
stacktrace: expect.any(Object),
418418
mechanism: {
419419
data: {

packages/utils/src/eventbuilder.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,26 @@ export function exceptionFromError(stackParser: StackParser, error: Error): Exce
3939
return exception;
4040
}
4141

42+
function getMessageForObject(exception: object): string {
43+
if ('name' in exception && typeof exception.name === 'string') {
44+
let message = `'${exception.name}' captured as exception`;
45+
46+
if ('message' in exception && typeof exception.message === 'string') {
47+
message += ` with message '${exception.message}'`;
48+
}
49+
50+
return message;
51+
} else if ('message' in exception && typeof exception.message === 'string') {
52+
return exception.message;
53+
} else {
54+
// This will allow us to group events based on top-level keys
55+
// which is much better than creating new group when any key/value change
56+
return `Object captured as exception with keys: ${extractExceptionKeysForMessage(
57+
exception as Record<string, unknown>,
58+
)}`;
59+
}
60+
}
61+
4262
/**
4363
* Builds and Event from a Exception
4464
* @hidden
@@ -59,17 +79,14 @@ export function eventFromUnknownInput(
5979

6080
if (!isError(exception)) {
6181
if (isPlainObject(exception)) {
62-
// This will allow us to group events based on top-level keys
63-
// which is much better than creating new group when any key/value change
64-
const message = `Non-Error exception captured with keys: ${extractExceptionKeysForMessage(exception)}`;
65-
6682
const hub = getCurrentHub();
6783
const client = hub.getClient();
6884
const normalizeDepth = client && client.getOptions().normalizeDepth;
6985
hub.configureScope(scope => {
7086
scope.setExtra('__serialized__', normalizeToSize(exception, normalizeDepth));
7187
});
7288

89+
const message = getMessageForObject(exception);
7390
ex = (hint && hint.syntheticException) || new Error(message);
7491
(ex as Error).message = message;
7592
} else {
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import type { Hub } from '@sentry/types';
2+
3+
import { createStackParser, eventFromUnknownInput, nodeStackLineParser } from '../src';
4+
5+
function getCurrentHub(): Hub {
6+
// Some fake hub to get us through
7+
return { getClient: () => undefined, configureScope: () => {} } as unknown as Hub;
8+
}
9+
10+
const stackParser = createStackParser(nodeStackLineParser());
11+
12+
describe('eventFromUnknownInput', () => {
13+
test('object with useless props', () => {
14+
const event = eventFromUnknownInput(getCurrentHub, stackParser, { foo: { bar: 'baz' }, prop: 1 });
15+
expect(event.exception?.values?.[0].value).toBe('Object captured as exception with keys: foo, prop');
16+
});
17+
18+
test('object with name prop', () => {
19+
const event = eventFromUnknownInput(getCurrentHub, stackParser, { foo: { bar: 'baz' }, name: 'BadType' });
20+
expect(event.exception?.values?.[0].value).toBe("'BadType' captured as exception");
21+
});
22+
23+
test('object with name and message props', () => {
24+
const event = eventFromUnknownInput(getCurrentHub, stackParser, { message: 'went wrong', name: 'BadType' });
25+
expect(event.exception?.values?.[0].value).toBe("'BadType' captured as exception with message 'went wrong'");
26+
});
27+
28+
test('object with message prop', () => {
29+
const event = eventFromUnknownInput(getCurrentHub, stackParser, { foo: { bar: 'baz' }, message: 'Some message' });
30+
expect(event.exception?.values?.[0].value).toBe('Some message');
31+
});
32+
});

0 commit comments

Comments
 (0)