Skip to content

Commit b623a68

Browse files
author
Luca Forstner
authored
fix(node): Fix tRPC middleware typing (#9540)
1 parent 27686ba commit b623a68

File tree

1 file changed

+39
-25
lines changed

1 file changed

+39
-25
lines changed

packages/node/src/handlers.ts

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
dropUndefinedKeys,
1717
extractPathForTransaction,
1818
isString,
19+
isThenable,
1920
logger,
2021
normalize,
2122
tracingContextFromHeaders,
@@ -326,7 +327,7 @@ interface SentryTrpcMiddlewareOptions {
326327

327328
interface TrpcMiddlewareArguments<T> {
328329
path: string;
329-
type: 'query' | 'mutation' | 'subscription';
330+
type: string;
330331
next: () => T;
331332
rawInput: unknown;
332333
}
@@ -338,7 +339,7 @@ interface TrpcMiddlewareArguments<T> {
338339
* e.g. Express Request Handlers or Next.js SDK.
339340
*/
340341
export function trpcMiddleware(options: SentryTrpcMiddlewareOptions = {}) {
341-
return async function <T>({ path, type, next, rawInput }: TrpcMiddlewareArguments<T>): Promise<T> {
342+
return function <T>({ path, type, next, rawInput }: TrpcMiddlewareArguments<T>): T {
342343
const hub = getCurrentHub();
343344
const clientOptions = hub.getClient()?.getOptions();
344345
const sentryTransaction = hub.getScope().getTransaction();
@@ -358,36 +359,49 @@ export function trpcMiddleware(options: SentryTrpcMiddlewareOptions = {}) {
358359
sentryTransaction.setContext('trpc', trpcContext);
359360
}
360361

361-
function captureError(e: unknown): void {
362-
captureException(e, scope => {
363-
scope.addEventProcessor(event => {
364-
addExceptionMechanism(event, {
365-
handled: false,
362+
function shouldCaptureError(e: unknown): boolean {
363+
if (typeof e === 'object' && e && 'code' in e) {
364+
// Is likely TRPCError - we only want to capture internal server errors
365+
return e.code === 'INTERNAL_SERVER_ERROR';
366+
} else {
367+
// Is likely random error that bubbles up
368+
return true;
369+
}
370+
}
371+
372+
function handleErrorCase(e: unknown): void {
373+
if (shouldCaptureError(e)) {
374+
captureException(e, scope => {
375+
scope.addEventProcessor(event => {
376+
addExceptionMechanism(event, {
377+
handled: false,
378+
});
379+
return event;
366380
});
367-
return event;
368-
});
369381

370-
return scope;
371-
});
382+
return scope;
383+
});
384+
}
372385
}
373386

374-
try {
375-
return await next();
376-
} catch (e: unknown) {
377-
if (typeof e === 'object' && e) {
378-
if ('code' in e) {
379-
// Is likely TRPCError - we only want to capture internal server errors
380-
if (e.code === 'INTERNAL_SERVER_ERROR') {
381-
captureError(e);
382-
}
383-
} else {
384-
// Is likely random error that bubbles up
385-
captureError(e);
386-
}
387-
}
387+
let maybePromiseResult;
388388

389+
try {
390+
maybePromiseResult = next();
391+
} catch (e) {
392+
handleErrorCase(e);
389393
throw e;
390394
}
395+
396+
if (isThenable(maybePromiseResult)) {
397+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
398+
Promise.resolve(maybePromiseResult).then(null, e => {
399+
handleErrorCase(e);
400+
});
401+
}
402+
403+
// We return the original promise just to be safe.
404+
return maybePromiseResult;
391405
};
392406
}
393407

0 commit comments

Comments
 (0)