Skip to content

Commit

Permalink
feat(node): Improve non-error messages (#9026)
Browse files Browse the repository at this point in the history
  • Loading branch information
timfish committed Sep 15, 2023
1 parent 042e7ce commit 4a4366d
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ test('should capture an empty object', async () => {
values: [
{
type: 'Error',
value: 'Non-Error exception captured with keys: [object has no keys]',
value: 'Object captured as exception with keys: [object has no keys]',
mechanism: {
type: 'generic',
handled: true,
Expand Down
8 changes: 4 additions & 4 deletions packages/remix/test/integration/test/server/action.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,8 @@ describe.each(['builtin', 'express'])('Remix API Actions with adapter = %s', ada
{
type: 'Error',
value: useV2
? 'Non-Error exception captured with keys: data, internal, status, statusText'
: 'Non-Error exception captured with keys: data',
? 'Object captured as exception with keys: data, internal, status, statusText'
: 'Object captured as exception with keys: data',
stacktrace: expect.any(Object),
mechanism: {
data: {
Expand Down Expand Up @@ -412,8 +412,8 @@ describe.each(['builtin', 'express'])('Remix API Actions with adapter = %s', ada
{
type: 'Error',
value: useV2
? 'Non-Error exception captured with keys: data, internal, status, statusText'
: 'Non-Error exception captured with keys: [object has no keys]',
? 'Object captured as exception with keys: data, internal, status, statusText'
: 'Object captured as exception with keys: [object has no keys]',
stacktrace: expect.any(Object),
mechanism: {
data: {
Expand Down
25 changes: 21 additions & 4 deletions packages/utils/src/eventbuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,26 @@ export function exceptionFromError(stackParser: StackParser, error: Error): Exce
return exception;
}

function getMessageForObject(exception: object): string {
if ('name' in exception && typeof exception.name === 'string') {
let message = `'${exception.name}' captured as exception`;

if ('message' in exception && typeof exception.message === 'string') {
message += ` with message '${exception.message}'`;
}

return message;
} else if ('message' in exception && typeof exception.message === 'string') {
return exception.message;
} else {
// This will allow us to group events based on top-level keys
// which is much better than creating new group when any key/value change
return `Object captured as exception with keys: ${extractExceptionKeysForMessage(
exception as Record<string, unknown>,
)}`;
}
}

/**
* Builds and Event from a Exception
* @hidden
Expand All @@ -59,17 +79,14 @@ export function eventFromUnknownInput(

if (!isError(exception)) {
if (isPlainObject(exception)) {
// This will allow us to group events based on top-level keys
// which is much better than creating new group when any key/value change
const message = `Non-Error exception captured with keys: ${extractExceptionKeysForMessage(exception)}`;

const hub = getCurrentHub();
const client = hub.getClient();
const normalizeDepth = client && client.getOptions().normalizeDepth;
hub.configureScope(scope => {
scope.setExtra('__serialized__', normalizeToSize(exception, normalizeDepth));
});

const message = getMessageForObject(exception);
ex = (hint && hint.syntheticException) || new Error(message);
(ex as Error).message = message;
} else {
Expand Down
32 changes: 32 additions & 0 deletions packages/utils/test/eventbuilder.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { Hub } from '@sentry/types';

import { createStackParser, eventFromUnknownInput, nodeStackLineParser } from '../src';

function getCurrentHub(): Hub {
// Some fake hub to get us through
return { getClient: () => undefined, configureScope: () => {} } as unknown as Hub;
}

const stackParser = createStackParser(nodeStackLineParser());

describe('eventFromUnknownInput', () => {
test('object with useless props', () => {
const event = eventFromUnknownInput(getCurrentHub, stackParser, { foo: { bar: 'baz' }, prop: 1 });
expect(event.exception?.values?.[0].value).toBe('Object captured as exception with keys: foo, prop');
});

test('object with name prop', () => {
const event = eventFromUnknownInput(getCurrentHub, stackParser, { foo: { bar: 'baz' }, name: 'BadType' });
expect(event.exception?.values?.[0].value).toBe("'BadType' captured as exception");
});

test('object with name and message props', () => {
const event = eventFromUnknownInput(getCurrentHub, stackParser, { message: 'went wrong', name: 'BadType' });
expect(event.exception?.values?.[0].value).toBe("'BadType' captured as exception with message 'went wrong'");
});

test('object with message prop', () => {
const event = eventFromUnknownInput(getCurrentHub, stackParser, { foo: { bar: 'baz' }, message: 'Some message' });
expect(event.exception?.values?.[0].value).toBe('Some message');
});
});

0 comments on commit 4a4366d

Please sign in to comment.