Skip to content

Add mechanism to captureException calls #17237

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
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/aws-serverless/src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,11 +306,11 @@ export function wrapHandler<TEvent, TResult>(
if (options.captureAllSettledReasons && Array.isArray(rv) && isPromiseAllSettledResult(rv)) {
const reasons = getRejectedReasons(rv);
reasons.forEach(exception => {
captureException(exception, scope => markEventUnhandled(scope));
captureException(exception, scope => markEventUnhandled(scope, 'aws-serverless.promise'));
});
}
} catch (e) {
captureException(e, scope => markEventUnhandled(scope));
captureException(e, scope => markEventUnhandled(scope, 'aws-serverless.handler'));
throw e;
} finally {
clearTimeout(timeoutWarningTimer);
Expand Down
4 changes: 2 additions & 2 deletions packages/aws-serverless/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ const headerGetter: TextMapGetter<APIGatewayProxyEventHeaders> = {
/**
* Marks an event as unhandled by adding a span processor to the passed scope.
*/
export function markEventUnhandled(scope: Scope): Scope {
export function markEventUnhandled(scope: Scope, type = 'aws-serverless'): Scope {
scope.addEventProcessor(event => {
addExceptionMechanism(event, { handled: false });
addExceptionMechanism(event, { handled: false, type });
return event;
});

Expand Down
7 changes: 6 additions & 1 deletion packages/browser/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,12 @@ export function wrap<T extends WrappableFunction, NonFunction>(
return event;
});

captureException(ex);
captureException(ex, {
mechanism: {
handled: false,
type: 'browser',
},
});
});

throw ex;
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1159,6 +1159,10 @@ export abstract class Client<O extends ClientOptions = ClientOptions> {
}

this.captureException(reason, {
mechanism: {
handled: false,
type: 'internal',
},
data: {
__sentry__: true,
},
Expand Down
6 changes: 6 additions & 0 deletions packages/core/src/integrations/supabase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ function instrumentAuthOperation(operation: AuthOperationFn, isAdmin = false): A
captureException(res.error, {
mechanism: {
handled: false,
type: 'supabase',
},
});
} else {
Expand All @@ -252,6 +253,7 @@ function instrumentAuthOperation(operation: AuthOperationFn, isAdmin = false): A
captureException(err, {
mechanism: {
handled: false,
type: 'supabase',
},
});

Expand Down Expand Up @@ -417,6 +419,10 @@ function instrumentPostgRESTFilterBuilder(PostgRESTFilterBuilder: PostgRESTFilte
}

captureException(err, {
mechanism: {
handled: false,
type: 'supabase',
},
contexts: {
supabase: supabaseContext,
},
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/trpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export interface SentryTrpcMiddlewareArguments<T> {
getRawInput?: () => Promise<unknown>;
}

const trpcCaptureContext = { mechanism: { handled: false, data: { function: 'trpcMiddleware' } } };
const trpcCaptureContext = { mechanism: { handled: false, type: 'trpc', data: { function: 'trpcMiddleware' } } };

function captureIfError(nextResult: unknown): void {
// TODO: Set span status based on what TRPCError was encountered
Expand Down
8 changes: 7 additions & 1 deletion packages/core/src/utils/openai/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ function instrumentMethod<T extends unknown[], R>(
captureException(error, {
mechanism: {
handled: false,
type: 'openai',
},
});
span.end();
Expand All @@ -230,7 +231,12 @@ function instrumentMethod<T extends unknown[], R>(
addResponseAttributes(span, result, finalOptions.recordOutputs);
return result;
} catch (error) {
captureException(error);
captureException(error, {
mechanism: {
handled: false,
type: 'openai',
},
});
throw error;
}
},
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/utils/openai/streaming.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ function processResponsesApiEvent(
captureException(streamEvent, {
mechanism: {
handled: false,
type: 'openai',
},
});
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function _wrapCloudEventFunction(

const newCallback = domainify((...args: unknown[]) => {
if (args[0] !== null && args[0] !== undefined) {
captureException(args[0], scope => markEventUnhandled(scope));
captureException(args[0], scope => markEventUnhandled(scope, 'google-cloud-serverless.cloud_event'));
}
span.end();

Expand All @@ -69,7 +69,7 @@ function _wrapCloudEventFunction(
return handleCallbackErrors(
() => (fn as CloudEventFunctionWithCallback)(context, newCallback),
err => {
captureException(err, scope => markEventUnhandled(scope));
captureException(err, scope => markEventUnhandled(scope, 'google-cloud-serverless.cloud_event'));
},
);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/google-cloud-serverless/src/gcpfunction/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function _wrapEventFunction<F extends EventFunction | EventFunctionWithCallback>

const newCallback = domainify((...args: unknown[]) => {
if (args[0] !== null && args[0] !== undefined) {
captureException(args[0], scope => markEventUnhandled(scope));
captureException(args[0], scope => markEventUnhandled(scope, 'google-cloud-serverless.event'));
}
span.end();

Expand All @@ -72,7 +72,7 @@ function _wrapEventFunction<F extends EventFunction | EventFunctionWithCallback>
return handleCallbackErrors(
() => (fn as EventFunctionWithCallback)(data, context, newCallback),
err => {
captureException(err, scope => markEventUnhandled(scope));
captureException(err, scope => markEventUnhandled(scope, 'google-cloud-serverless.event'));
},
);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/google-cloud-serverless/src/gcpfunction/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ function _wrapHttpFunction(fn: HttpFunction, options: Partial<WrapperOptions>):
return handleCallbackErrors(
() => fn(req, res),
err => {
captureException(err, scope => markEventUnhandled(scope));
captureException(err, scope => markEventUnhandled(scope, 'google-cloud-serverless.http'));
},
);
},
Expand Down
4 changes: 2 additions & 2 deletions packages/google-cloud-serverless/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ export function proxyFunction<A extends any[], R, F extends (...args: A) => R>(
/**
* Marks an event as unhandled by adding a span processor to the passed scope.
*/
export function markEventUnhandled(scope: Scope): Scope {
export function markEventUnhandled(scope: Scope, type = 'google-cloud-serverless'): Scope {
scope.addEventProcessor(event => {
addExceptionMechanism(event, { handled: false });
addExceptionMechanism(event, { handled: false, type });
return event;
});

Expand Down
21 changes: 18 additions & 3 deletions packages/nestjs/src/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,22 @@ export const SentryCron = (monitorSlug: string, monitorConfig?: MonitorConfig):
try {
result = originalMethod.apply(this, args);
} catch (e) {
captureException(e);
captureException(e, {
mechanism: {
handled: false,
type: 'nestjs.cron',
},
});
throw e;
}
if (isThenable(result)) {
return result.then(undefined, e => {
captureException(e);
captureException(e, {
mechanism: {
handled: false,
type: 'nestjs.cron',
},
});
throw e;
});
}
Expand Down Expand Up @@ -77,7 +87,12 @@ export function SentryExceptionCaptured() {
return originalCatch.apply(this, [exception, host, ...args]);
}

captureException(exception);
captureException(exception, {
mechanism: {
handled: true, // User provided exception filter to handle the error
type: 'nestjs.exception-filter',
},
});
return originalCatch.apply(this, [exception, host, ...args]);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,12 @@ export class SentryNestEventInstrumentation extends InstrumentationBase {
return result;
} catch (error) {
// exceptions from event handlers are not caught by global error filter
captureException(error);
captureException(error, {
mechanism: {
handled: false,
type: 'nestjs.event',
},
});
throw error;
}
});
Expand Down
28 changes: 24 additions & 4 deletions packages/nestjs/src/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,12 @@ class SentryGlobalFilter extends BaseExceptionFilter {
this._logger.error(exception.message, exception.stack);
}

captureException(exception);
captureException(exception, {
mechanism: {
handled: false,
type: 'nestjs.graphql',
},
});
throw exception;
}

Expand All @@ -117,15 +122,25 @@ class SentryGlobalFilter extends BaseExceptionFilter {
// Handle any other kind of error
if (!(exception instanceof Error)) {
if (!isExpectedError(exception)) {
captureException(exception);
captureException(exception, {
mechanism: {
handled: false,
type: 'nestjs.rpc',
},
});
}
throw exception;
}

// In this case we're likely running into an RpcException, which the user should handle with a dedicated filter
// https://github.com/nestjs/nest/blob/master/sample/03-microservices/src/common/filters/rpc-exception.filter.ts
if (!isExpectedError(exception)) {
captureException(exception);
captureException(exception, {
mechanism: {
handled: false,
type: 'nestjs.rpc',
},
});
}

this._logger.warn(
Expand All @@ -139,7 +154,12 @@ class SentryGlobalFilter extends BaseExceptionFilter {

// HTTP exceptions
if (!isExpectedError(exception)) {
captureException(exception);
captureException(exception, {
mechanism: {
handled: false,
type: 'nestjs.http',
},
});
}

return super.catch(exception, host);
Expand Down
1 change: 1 addition & 0 deletions packages/nextjs/src/common/captureRequestError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export function captureRequestError(error: unknown, request: RequestInfo, errorC
captureException(error, {
mechanism: {
handled: false,
type: 'nextjs.request',
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export async function captureUnderscoreErrorException(contextOrProps: ContextOrP
// is what passing a string to `captureException` will wind up doing)
captureException(err || `_error.js called with falsy error (${err})`, {
mechanism: {
type: 'instrument',
type: 'nextjs.error',
handled: false,
data: {
function: '_error.getInitialProps',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export function wrapApiHandlerWithSentry(apiHandler: NextApiHandler, parameteriz

captureException(objectifiedErr, {
mechanism: {
type: 'instrument',
type: 'nextjs.api',
handled: false,
data: {
wrapped_handler: wrappingTarget.name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export function wrapPageComponentWithSentry(pageComponent: FunctionComponent | C
captureException(e, {
mechanism: {
handled: false,
type: 'nextjs.page',
},
});
throw e;
Expand Down Expand Up @@ -77,6 +78,7 @@ export function wrapPageComponentWithSentry(pageComponent: FunctionComponent | C
captureException(e, {
mechanism: {
handled: false,
type: 'nextjs.page',
},
});
throw e;
Expand Down
4 changes: 2 additions & 2 deletions packages/nextjs/src/common/utils/wrapperUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export function withErrorInstrumentation<F extends (...args: any[]) => any>(
return await origFunction.apply(this, origFunctionArguments);
} catch (e) {
// TODO: Extract error logic from `withSentry` in here or create a new wrapper with said logic or something like that.
captureException(e, { mechanism: { handled: false } });
captureException(e, { mechanism: { handled: false, type: 'nextjs' } });
throw e;
}
};
Expand Down Expand Up @@ -99,7 +99,7 @@ export async function callDataFetcherTraced<F extends (...args: any[]) => Promis
try {
return await origFunction(...origFunctionArgs);
} catch (e) {
captureException(e, { mechanism: { handled: false } });
captureException(e, { mechanism: { handled: false, type: 'nextjs' } });
throw e;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ async function withServerActionInstrumentationImplementation<A extends (...args:
captureException(error, {
mechanism: {
handled: false,
type: 'nextjs.server-action',
},
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ export function wrapGenerationFunctionWithSentry<F extends (...args: any[]) => a
captureException(err, {
mechanism: {
handled: false,
type: 'nextjs.generation-function',
},
});
}
Expand Down
2 changes: 1 addition & 1 deletion packages/nextjs/src/common/wrapMiddlewareWithSentry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export function wrapMiddlewareWithSentry<H extends EdgeRouteHandler>(
error => {
captureException(error, {
mechanism: {
type: 'instrument',
type: 'nextjs.middleware',
handled: false,
},
});
Expand Down
1 change: 1 addition & 0 deletions packages/nextjs/src/common/wrapRouteHandlerWithSentry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export function wrapRouteHandlerWithSentry<F extends (...args: any[]) => any>(
captureException(error, {
mechanism: {
handled: false,
type: 'nextjs.route',
},
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ export function wrapServerComponentWithSentry<F extends (...args: any[]) => any>
captureException(error, {
mechanism: {
handled: false,
type: 'nextjs.server-component',
},
});
}
Expand Down
2 changes: 1 addition & 1 deletion packages/nextjs/src/edge/wrapApiHandlerWithSentry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export function wrapApiHandlerWithSentry<H extends EdgeRouteHandler>(
error => {
captureException(error, {
mechanism: {
type: 'instrument',
type: 'nextjs.edge',
handled: false,
},
});
Expand Down
Loading
Loading