Skip to content

Commit

Permalink
feat(v7): Deprecate and relocate trpcMiddleware (#11389)
Browse files Browse the repository at this point in the history
  • Loading branch information
lforst committed Apr 3, 2024
1 parent fdcd1ad commit 264d9b1
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"node": ">=12"
},
"scripts": {
"db-up": "docker-compose up -d",
"db-up": "docker compose up -d",
"generate": "prisma generate",
"migrate": "prisma migrate dev -n sentry-test",
"setup": "run-s --silent db-up generate migrate"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"node": ">=12"
},
"scripts": {
"db-up": "docker-compose up -d",
"db-up": "docker compose up -d",
"generate": "prisma generate",
"migrate": "prisma migrate dev -n sentry-test",
"setup": "run-s --silent db-up generate migrate"
Expand Down
1 change: 1 addition & 0 deletions packages/astro/src/index.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export {
inboundFiltersIntegration,
linkedErrorsIntegration,
Handlers,
trpcMiddleware,
setMeasurement,
getActiveSpan,
startSpan,
Expand Down
1 change: 1 addition & 0 deletions packages/bun/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ export {
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE,
trpcMiddleware,
} from '@sentry/node';

export { BunClient } from './client';
Expand Down
84 changes: 14 additions & 70 deletions packages/node/src/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,15 @@ import {
extractPathForTransaction,
extractRequestData,
isString,
isThenable,
logger,
normalize,
} from '@sentry/utils';

import type { NodeClient } from './client';
import { DEBUG_BUILD } from './debug-build';
// TODO (v8 / XXX) Remove this import
import type { ParseRequestOptions } from './requestDataDeprecated';
import { isAutoSessionTrackingEnabled } from './sdk';
import { trpcMiddleware as newTrpcMiddleware } from './trpc';

/**
* Express-compatible tracing handler.
Expand Down Expand Up @@ -316,80 +315,25 @@ export function errorHandler(options?: {
};
}

interface SentryTrpcMiddlewareOptions {
/** Whether to include procedure inputs in reported events. Defaults to `false`. */
attachRpcInput?: boolean;
}

interface TrpcMiddlewareArguments<T> {
path: string;
type: string;
next: () => T;
rawInput: unknown;
}

/**
* Sentry tRPC middleware that names the handling transaction after the called procedure.
*
* Use the Sentry tRPC middleware in combination with the Sentry server integration,
* e.g. Express Request Handlers or Next.js SDK.
*
* @deprecated Please use the top level export instead:
* ```
* // OLD
* import * as Sentry from '@sentry/node';
* Sentry.Handlers.trpcMiddleware();
*
* // NEW
* import * as Sentry from '@sentry/node';
* Sentry.trpcMiddleware();
* ```
*/
export function trpcMiddleware(options: SentryTrpcMiddlewareOptions = {}) {
return function <T>({ path, type, next, rawInput }: TrpcMiddlewareArguments<T>): T {
const clientOptions = getClient()?.getOptions();
// eslint-disable-next-line deprecation/deprecation
const sentryTransaction = getCurrentScope().getTransaction();

if (sentryTransaction) {
sentryTransaction.updateName(`trpc/${path}`);
sentryTransaction.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');
sentryTransaction.op = 'rpc.server';

const trpcContext: Record<string, unknown> = {
procedure_type: type,
};

if (options.attachRpcInput !== undefined ? options.attachRpcInput : clientOptions?.sendDefaultPii) {
trpcContext.input = normalize(rawInput);
}

// TODO: Can we rewrite this to an attribute? Or set this on the scope?
// eslint-disable-next-line deprecation/deprecation
sentryTransaction.setContext('trpc', trpcContext);
}

function captureIfError(nextResult: { ok: false; error?: Error } | { ok: true }): void {
if (!nextResult.ok) {
captureException(nextResult.error, { mechanism: { handled: false, data: { function: 'trpcMiddleware' } } });
}
}

let maybePromiseResult;
try {
maybePromiseResult = next();
} catch (e) {
captureException(e, { mechanism: { handled: false, data: { function: 'trpcMiddleware' } } });
throw e;
}

if (isThenable(maybePromiseResult)) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
Promise.resolve(maybePromiseResult).then(
nextResult => {
captureIfError(nextResult as any);
},
e => {
captureException(e, { mechanism: { handled: false, data: { function: 'trpcMiddleware' } } });
},
);
} else {
captureIfError(maybePromiseResult as any);
}

// We return the original promise just to be safe.
return maybePromiseResult;
};
}
// eslint-disable-next-line deprecation/deprecation
export const trpcMiddleware = newTrpcMiddleware;

// TODO (v8 / #5257): Remove this
// eslint-disable-next-line deprecation/deprecation
Expand Down
2 changes: 2 additions & 0 deletions packages/node/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ export type { AnrIntegrationOptions } from './integrations/anr/common';

export { Handlers };

export { trpcMiddleware } from './trpc';

export { hapiErrorPlugin } from './integrations/hapi';

import { instrumentCron } from './cron/cron';
Expand Down
77 changes: 77 additions & 0 deletions packages/node/src/trpc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, captureException, getClient, getCurrentScope } from '@sentry/core';
import { isThenable, normalize } from '@sentry/utils';

interface SentryTrpcMiddlewareOptions {
/** Whether to include procedure inputs in reported events. Defaults to `false`. */
attachRpcInput?: boolean;
}

interface TrpcMiddlewareArguments<T> {
path: string;
type: string;
next: () => T;
rawInput: unknown;
}

/**
* Sentry tRPC middleware that names the handling transaction after the called procedure.
*
* Use the Sentry tRPC middleware in combination with the Sentry server integration,
* e.g. Express Request Handlers or Next.js SDK.
*/
export function trpcMiddleware(options: SentryTrpcMiddlewareOptions = {}) {
return function <T>({ path, type, next, rawInput }: TrpcMiddlewareArguments<T>): T {
const clientOptions = getClient()?.getOptions();
// eslint-disable-next-line deprecation/deprecation
const sentryTransaction = getCurrentScope().getTransaction();

if (sentryTransaction) {
sentryTransaction.updateName(`trpc/${path}`);
sentryTransaction.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');
sentryTransaction.op = 'rpc.server';

const trpcContext: Record<string, unknown> = {
procedure_type: type,
};

if (options.attachRpcInput !== undefined ? options.attachRpcInput : clientOptions?.sendDefaultPii) {
trpcContext.input = normalize(rawInput);
}

// TODO: Can we rewrite this to an attribute? Or set this on the scope?
// eslint-disable-next-line deprecation/deprecation
sentryTransaction.setContext('trpc', trpcContext);
}

function captureIfError(nextResult: { ok: false; error?: Error } | { ok: true }): void {
if (!nextResult.ok) {
captureException(nextResult.error, { mechanism: { handled: false, data: { function: 'trpcMiddleware' } } });
}
}

let maybePromiseResult;
try {
maybePromiseResult = next();
} catch (e) {
captureException(e, { mechanism: { handled: false, data: { function: 'trpcMiddleware' } } });
throw e;
}

if (isThenable(maybePromiseResult)) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
Promise.resolve(maybePromiseResult).then(
nextResult => {
captureIfError(nextResult as any);
},
e => {
captureException(e, { mechanism: { handled: false, data: { function: 'trpcMiddleware' } } });
},
);
} else {
captureIfError(maybePromiseResult as any);
}

// We return the original promise just to be safe.
return maybePromiseResult;
};
}
1 change: 1 addition & 0 deletions packages/remix/src/index.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export {
inboundFiltersIntegration,
linkedErrorsIntegration,
Handlers,
trpcMiddleware,
setMeasurement,
getActiveSpan,
startSpan,
Expand Down
1 change: 1 addition & 0 deletions packages/serverless/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export {
// eslint-disable-next-line deprecation/deprecation
deepReadDirSync,
Handlers,
trpcMiddleware,
// eslint-disable-next-line deprecation/deprecation
Integrations,
setMeasurement,
Expand Down
1 change: 1 addition & 0 deletions packages/sveltekit/src/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export {
inboundFiltersIntegration,
linkedErrorsIntegration,
Handlers,
trpcMiddleware,
setMeasurement,
getActiveSpan,
startSpan,
Expand Down

0 comments on commit 264d9b1

Please sign in to comment.