Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/core/src/server-runtime-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { eventFromMessage, eventFromUnknownInput, logger, resolvedSyncPromise, u
import { BaseClient } from './baseclient';
import { createCheckInEnvelope } from './checkin';
import { DEBUG_BUILD } from './debug-build';
import { getCurrentHub } from './hub';
import { getClient } from './exports';
import type { Scope } from './scope';
import { SessionFlusher } from './sessionflusher';
import { addTracingExtensions, getDynamicSamplingContextFromClient } from './tracing';
Expand Down Expand Up @@ -50,7 +50,7 @@ export class ServerRuntimeClient<
* @inheritDoc
*/
public eventFromException(exception: unknown, hint?: EventHint): PromiseLike<Event> {
return resolvedSyncPromise(eventFromUnknownInput(getCurrentHub, this._options.stackParser, exception, hint));
return resolvedSyncPromise(eventFromUnknownInput(getClient(), this._options.stackParser, exception, hint));
}

/**
Expand Down
7 changes: 4 additions & 3 deletions packages/deno/src/integrations/globalhandlers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { ServerRuntimeClient } from '@sentry/core';
import { flush, getCurrentHub } from '@sentry/core';
import { getClient, getCurrentHub, getCurrentScope } from '@sentry/core';
import { flush } from '@sentry/core';
import type { Event, Hub, Integration, Primitive, StackParser } from '@sentry/types';
import { eventFromUnknownInput, isPrimitive } from '@sentry/utils';

Expand Down Expand Up @@ -70,7 +71,7 @@ function installGlobalErrorHandler(): void {
const [hub, stackParser] = getHubAndOptions();
const { message, error } = data;

const event = eventFromUnknownInput(getCurrentHub, stackParser, error || message);
const event = eventFromUnknownInput(getClient(), stackParser, error || message);

event.level = 'fatal';

Expand Down Expand Up @@ -113,7 +114,7 @@ function installGlobalUnhandledRejectionHandler(): void {

const event = isPrimitive(error)
? eventFromRejectionWithPrimitive(error)
: eventFromUnknownInput(getCurrentHub, stackParser, error, undefined);
: eventFromUnknownInput(getClient(), stackParser, error, undefined);

event.level = 'fatal';

Expand Down
85 changes: 53 additions & 32 deletions packages/node/test/eventbuilders.test.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,51 @@
import type { Client } from '@sentry/types';
import type { Hub } from '@sentry/types';
import { eventFromUnknownInput } from '@sentry/utils';

import { Scope, defaultStackParser, getCurrentHub } from '../src';
import { defaultStackParser } from '../src';

const testScope = new Scope();

jest.mock('@sentry/core', () => {
const original = jest.requireActual('@sentry/core');
return {
...original,
getCurrentHub(): {
getClient(): Client;
getScope(): Scope;
} {
return {
getClient(): any {
return {
getOptions(): any {
return { normalizeDepth: 6 };
describe('eventFromUnknownInput', () => {
test('uses normalizeDepth from init options', () => {
const deepObject = {
a: {
b: {
c: {
d: {
e: {
f: {
g: 'foo',
},
},
},
};
},
getScope(): Scope {
return testScope;
},
},
};
},
};
});
},
};

afterEach(() => {
jest.resetAllMocks();
});
const client = {
getOptions(): any {
return { normalizeDepth: 6 };
},
} as any;
const event = eventFromUnknownInput(client, defaultStackParser, deepObject);

describe('eventFromUnknownInput', () => {
test('uses normalizeDepth from init options', () => {
const serializedObject = event.extra?.__serialized__;
expect(serializedObject).toBeDefined();
expect(serializedObject).toEqual({
a: {
b: {
c: {
d: {
e: {
f: '[Object]',
},
},
},
},
},
});
});

test('uses normalizeDepth from init options (passing getCurrentHub)', () => {
const deepObject = {
a: {
b: {
Expand All @@ -51,9 +62,19 @@ describe('eventFromUnknownInput', () => {
},
};

eventFromUnknownInput(getCurrentHub, defaultStackParser, deepObject);
const getCurrentHub = jest.fn(() => {
return {
getClient: () => ({
getOptions(): any {
return { normalizeDepth: 6 };
},
}),
} as unknown as Hub;
});

const event = eventFromUnknownInput(getCurrentHub, defaultStackParser, deepObject);

const serializedObject = (testScope as any)._extra.__serialized__;
const serializedObject = event.extra?.__serialized__;
expect(serializedObject).toBeDefined();
expect(serializedObject).toEqual({
a: {
Expand Down
20 changes: 15 additions & 5 deletions packages/utils/src/eventbuilder.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import type {
Client,
Event,
EventHint,
Exception,
Extras,
Hub,
Mechanism,
Severity,
Expand Down Expand Up @@ -61,14 +63,18 @@ function getMessageForObject(exception: object): string {

/**
* Builds and Event from a Exception
*
* TODO(v8): Remove getHub fallback
* @hidden
*/
export function eventFromUnknownInput(
getCurrentHub: () => Hub,
getHubOrClient: (() => Hub) | Client | undefined,
stackParser: StackParser,
exception: unknown,
hint?: EventHint,
): Event {
const client = typeof getHubOrClient === 'function' ? getHubOrClient().getClient() : getHubOrClient;

let ex: unknown = exception;
const providedMechanism: Mechanism | undefined =
hint && hint.data && (hint.data as { mechanism: Mechanism }).mechanism;
Expand All @@ -77,12 +83,12 @@ export function eventFromUnknownInput(
type: 'generic',
};

let extras: Extras | undefined;

if (!isError(exception)) {
if (isPlainObject(exception)) {
const hub = getCurrentHub();
const client = hub.getClient();
const normalizeDepth = client && client.getOptions().normalizeDepth;
hub.getScope().setExtra('__serialized__', normalizeToSize(exception, normalizeDepth));
extras = { ['__serialized__']: normalizeToSize(exception as Record<string, unknown>, normalizeDepth) };

const message = getMessageForObject(exception);
ex = (hint && hint.syntheticException) || new Error(message);
Expand All @@ -96,12 +102,16 @@ export function eventFromUnknownInput(
mechanism.synthetic = true;
}

const event = {
const event: Event = {
exception: {
values: [exceptionFromError(stackParser, ex as Error)],
},
};

if (extras) {
event.extra = extras;
}

addExceptionTypeValue(event, undefined, undefined);
addExceptionMechanism(event, mechanism);

Expand Down
5 changes: 5 additions & 0 deletions packages/utils/test/eventbuilder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,9 @@ describe('eventFromUnknownInput', () => {
const event = eventFromUnknownInput(getCurrentHub, stackParser, { foo: { bar: 'baz' }, message: 'Some message' });
expect(event.exception?.values?.[0].value).toBe('Some message');
});

test('passing client directly', () => {
const event = eventFromUnknownInput(undefined, stackParser, { foo: { bar: 'baz' }, prop: 1 });
expect(event.exception?.values?.[0].value).toBe('Object captured as exception with keys: foo, prop');
});
});