Skip to content

Commit 264d9b1

Browse files
author
Luca Forstner
authored
feat(v7): Deprecate and relocate trpcMiddleware (#11389)
1 parent fdcd1ad commit 264d9b1

File tree

10 files changed

+100
-72
lines changed

10 files changed

+100
-72
lines changed

dev-packages/node-integration-tests/suites/tracing-new/prisma-orm/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"node": ">=12"
88
},
99
"scripts": {
10-
"db-up": "docker-compose up -d",
10+
"db-up": "docker compose up -d",
1111
"generate": "prisma generate",
1212
"migrate": "prisma migrate dev -n sentry-test",
1313
"setup": "run-s --silent db-up generate migrate"

dev-packages/node-integration-tests/suites/tracing/prisma-orm/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"node": ">=12"
88
},
99
"scripts": {
10-
"db-up": "docker-compose up -d",
10+
"db-up": "docker compose up -d",
1111
"generate": "prisma generate",
1212
"migrate": "prisma migrate dev -n sentry-test",
1313
"setup": "run-s --silent db-up generate migrate"

packages/astro/src/index.server.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ export {
8383
inboundFiltersIntegration,
8484
linkedErrorsIntegration,
8585
Handlers,
86+
trpcMiddleware,
8687
setMeasurement,
8788
getActiveSpan,
8889
startSpan,

packages/bun/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ export {
125125
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
126126
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
127127
SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE,
128+
trpcMiddleware,
128129
} from '@sentry/node';
129130

130131
export { BunClient } from './client';

packages/node/src/handlers.ts

Lines changed: 14 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,15 @@ import {
2222
extractPathForTransaction,
2323
extractRequestData,
2424
isString,
25-
isThenable,
2625
logger,
27-
normalize,
2826
} from '@sentry/utils';
2927

3028
import type { NodeClient } from './client';
3129
import { DEBUG_BUILD } from './debug-build';
3230
// TODO (v8 / XXX) Remove this import
3331
import type { ParseRequestOptions } from './requestDataDeprecated';
3432
import { isAutoSessionTrackingEnabled } from './sdk';
33+
import { trpcMiddleware as newTrpcMiddleware } from './trpc';
3534

3635
/**
3736
* Express-compatible tracing handler.
@@ -316,80 +315,25 @@ export function errorHandler(options?: {
316315
};
317316
}
318317

319-
interface SentryTrpcMiddlewareOptions {
320-
/** Whether to include procedure inputs in reported events. Defaults to `false`. */
321-
attachRpcInput?: boolean;
322-
}
323-
324-
interface TrpcMiddlewareArguments<T> {
325-
path: string;
326-
type: string;
327-
next: () => T;
328-
rawInput: unknown;
329-
}
330-
331318
/**
332319
* Sentry tRPC middleware that names the handling transaction after the called procedure.
333320
*
334321
* Use the Sentry tRPC middleware in combination with the Sentry server integration,
335322
* e.g. Express Request Handlers or Next.js SDK.
323+
*
324+
* @deprecated Please use the top level export instead:
325+
* ```
326+
* // OLD
327+
* import * as Sentry from '@sentry/node';
328+
* Sentry.Handlers.trpcMiddleware();
329+
*
330+
* // NEW
331+
* import * as Sentry from '@sentry/node';
332+
* Sentry.trpcMiddleware();
333+
* ```
336334
*/
337-
export function trpcMiddleware(options: SentryTrpcMiddlewareOptions = {}) {
338-
return function <T>({ path, type, next, rawInput }: TrpcMiddlewareArguments<T>): T {
339-
const clientOptions = getClient()?.getOptions();
340-
// eslint-disable-next-line deprecation/deprecation
341-
const sentryTransaction = getCurrentScope().getTransaction();
342-
343-
if (sentryTransaction) {
344-
sentryTransaction.updateName(`trpc/${path}`);
345-
sentryTransaction.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');
346-
sentryTransaction.op = 'rpc.server';
347-
348-
const trpcContext: Record<string, unknown> = {
349-
procedure_type: type,
350-
};
351-
352-
if (options.attachRpcInput !== undefined ? options.attachRpcInput : clientOptions?.sendDefaultPii) {
353-
trpcContext.input = normalize(rawInput);
354-
}
355-
356-
// TODO: Can we rewrite this to an attribute? Or set this on the scope?
357-
// eslint-disable-next-line deprecation/deprecation
358-
sentryTransaction.setContext('trpc', trpcContext);
359-
}
360-
361-
function captureIfError(nextResult: { ok: false; error?: Error } | { ok: true }): void {
362-
if (!nextResult.ok) {
363-
captureException(nextResult.error, { mechanism: { handled: false, data: { function: 'trpcMiddleware' } } });
364-
}
365-
}
366-
367-
let maybePromiseResult;
368-
try {
369-
maybePromiseResult = next();
370-
} catch (e) {
371-
captureException(e, { mechanism: { handled: false, data: { function: 'trpcMiddleware' } } });
372-
throw e;
373-
}
374-
375-
if (isThenable(maybePromiseResult)) {
376-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
377-
Promise.resolve(maybePromiseResult).then(
378-
nextResult => {
379-
captureIfError(nextResult as any);
380-
},
381-
e => {
382-
captureException(e, { mechanism: { handled: false, data: { function: 'trpcMiddleware' } } });
383-
},
384-
);
385-
} else {
386-
captureIfError(maybePromiseResult as any);
387-
}
388-
389-
// We return the original promise just to be safe.
390-
return maybePromiseResult;
391-
};
392-
}
335+
// eslint-disable-next-line deprecation/deprecation
336+
export const trpcMiddleware = newTrpcMiddleware;
393337

394338
// TODO (v8 / #5257): Remove this
395339
// eslint-disable-next-line deprecation/deprecation

packages/node/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ export type { AnrIntegrationOptions } from './integrations/anr/common';
167167

168168
export { Handlers };
169169

170+
export { trpcMiddleware } from './trpc';
171+
170172
export { hapiErrorPlugin } from './integrations/hapi';
171173

172174
import { instrumentCron } from './cron/cron';

packages/node/src/trpc.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, captureException, getClient, getCurrentScope } from '@sentry/core';
2+
import { isThenable, normalize } from '@sentry/utils';
3+
4+
interface SentryTrpcMiddlewareOptions {
5+
/** Whether to include procedure inputs in reported events. Defaults to `false`. */
6+
attachRpcInput?: boolean;
7+
}
8+
9+
interface TrpcMiddlewareArguments<T> {
10+
path: string;
11+
type: string;
12+
next: () => T;
13+
rawInput: unknown;
14+
}
15+
16+
/**
17+
* Sentry tRPC middleware that names the handling transaction after the called procedure.
18+
*
19+
* Use the Sentry tRPC middleware in combination with the Sentry server integration,
20+
* e.g. Express Request Handlers or Next.js SDK.
21+
*/
22+
export function trpcMiddleware(options: SentryTrpcMiddlewareOptions = {}) {
23+
return function <T>({ path, type, next, rawInput }: TrpcMiddlewareArguments<T>): T {
24+
const clientOptions = getClient()?.getOptions();
25+
// eslint-disable-next-line deprecation/deprecation
26+
const sentryTransaction = getCurrentScope().getTransaction();
27+
28+
if (sentryTransaction) {
29+
sentryTransaction.updateName(`trpc/${path}`);
30+
sentryTransaction.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');
31+
sentryTransaction.op = 'rpc.server';
32+
33+
const trpcContext: Record<string, unknown> = {
34+
procedure_type: type,
35+
};
36+
37+
if (options.attachRpcInput !== undefined ? options.attachRpcInput : clientOptions?.sendDefaultPii) {
38+
trpcContext.input = normalize(rawInput);
39+
}
40+
41+
// TODO: Can we rewrite this to an attribute? Or set this on the scope?
42+
// eslint-disable-next-line deprecation/deprecation
43+
sentryTransaction.setContext('trpc', trpcContext);
44+
}
45+
46+
function captureIfError(nextResult: { ok: false; error?: Error } | { ok: true }): void {
47+
if (!nextResult.ok) {
48+
captureException(nextResult.error, { mechanism: { handled: false, data: { function: 'trpcMiddleware' } } });
49+
}
50+
}
51+
52+
let maybePromiseResult;
53+
try {
54+
maybePromiseResult = next();
55+
} catch (e) {
56+
captureException(e, { mechanism: { handled: false, data: { function: 'trpcMiddleware' } } });
57+
throw e;
58+
}
59+
60+
if (isThenable(maybePromiseResult)) {
61+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
62+
Promise.resolve(maybePromiseResult).then(
63+
nextResult => {
64+
captureIfError(nextResult as any);
65+
},
66+
e => {
67+
captureException(e, { mechanism: { handled: false, data: { function: 'trpcMiddleware' } } });
68+
},
69+
);
70+
} else {
71+
captureIfError(maybePromiseResult as any);
72+
}
73+
74+
// We return the original promise just to be safe.
75+
return maybePromiseResult;
76+
};
77+
}

packages/remix/src/index.server.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ export {
8787
inboundFiltersIntegration,
8888
linkedErrorsIntegration,
8989
Handlers,
90+
trpcMiddleware,
9091
setMeasurement,
9192
getActiveSpan,
9293
startSpan,

packages/serverless/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export {
7373
// eslint-disable-next-line deprecation/deprecation
7474
deepReadDirSync,
7575
Handlers,
76+
trpcMiddleware,
7677
// eslint-disable-next-line deprecation/deprecation
7778
Integrations,
7879
setMeasurement,

packages/sveltekit/src/server/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ export {
8181
inboundFiltersIntegration,
8282
linkedErrorsIntegration,
8383
Handlers,
84+
trpcMiddleware,
8485
setMeasurement,
8586
getActiveSpan,
8687
startSpan,

0 commit comments

Comments
 (0)