Skip to content

Commit aa06362

Browse files
committed
add comment and update mechanism
1 parent 9822576 commit aa06362

3 files changed

Lines changed: 41 additions & 16 deletions

File tree

dev-packages/e2e-tests/test-applications/tanstackstart-react/tests/errors.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ test('Sends server-side function error to Sentry with auto-instrumentation', asy
5151
type: 'Error',
5252
value: 'Sentry Server Function Test Error',
5353
mechanism: {
54-
type: 'auto.function.tanstackstart',
54+
type: 'auto.middleware.tanstackstart.server_function',
5555
handled: false,
5656
},
5757
},
@@ -82,7 +82,7 @@ test('Sends API route error to Sentry with auto-instrumentation', async ({ page
8282
type: 'Error',
8383
value: 'Sentry API Route Test Error',
8484
mechanism: {
85-
type: 'auto.function.tanstackstart',
85+
type: 'auto.middleware.tanstackstart.request',
8686
handled: false,
8787
},
8888
},
@@ -93,6 +93,8 @@ test('Sends API route error to Sentry with auto-instrumentation', async ({ page
9393
expect(errorEvent.transaction).toBe('GET /api/error');
9494
});
9595

96+
// the sentry global middleware does not capture errors from SSR loader errors since they are serialized before they reach the middleware layer
97+
// this test verifies that the error is in fact not sent to Sentry
9698
test('Does not send SSR loader error to Sentry', async ({ baseURL, page }) => {
9799
let errorEventOccurred = false;
98100

packages/tanstackstart-react/src/server/globalMiddleware.ts

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@ import { addNonEnumerableProperty, captureException } from '@sentry/core';
22
import type { TanStackMiddlewareBase } from '../common/types';
33
import { SENTRY_INTERNAL } from './middleware';
44

5-
async function sentryMiddlewareHandler({ next }: { next: () => Promise<unknown> }): Promise<unknown> {
6-
try {
7-
return await next();
8-
} catch (e) {
9-
captureException(e, {
10-
mechanism: { type: 'auto.function.tanstackstart', handled: false },
11-
});
12-
throw e;
13-
}
5+
function createSentryMiddlewareHandler(mechanismType: string) {
6+
return async function sentryMiddlewareHandler({ next }: { next: () => Promise<unknown> }): Promise<unknown> {
7+
try {
8+
return await next();
9+
} catch (e) {
10+
captureException(e, {
11+
mechanism: { type: mechanismType, handled: false },
12+
});
13+
throw e;
14+
}
15+
};
1416
}
1517

1618
/**
@@ -19,8 +21,10 @@ async function sentryMiddlewareHandler({ next }: { next: () => Promise<unknown>
1921
*/
2022
export const sentryGlobalRequestMiddleware: TanStackMiddlewareBase = {
2123
'~types': undefined,
22-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
23-
options: { server: sentryMiddlewareHandler as (...args: any[]) => any },
24+
25+
options: {
26+
server: createSentryMiddlewareHandler('auto.middleware.tanstackstart.request') as (...args: any[]) => any,
27+
},
2428
};
2529

2630
/**
@@ -29,8 +33,10 @@ export const sentryGlobalRequestMiddleware: TanStackMiddlewareBase = {
2933
*/
3034
export const sentryGlobalFunctionMiddleware: TanStackMiddlewareBase = {
3135
'~types': undefined,
32-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
33-
options: { server: sentryMiddlewareHandler as (...args: any[]) => any },
36+
37+
options: {
38+
server: createSentryMiddlewareHandler('auto.middleware.tanstackstart.server_function') as (...args: any[]) => any,
39+
},
3440
};
3541

3642
// Mark as internal so the Vite auto-instrumentation plugin skips these middleware

packages/tanstackstart-react/test/server/globalMiddleware.test.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ describe('sentryGlobalRequestMiddleware', () => {
2828
await expect(serverFn({ next })).rejects.toThrow('test error');
2929

3030
expect(captureExceptionSpy).toHaveBeenCalledWith(error, {
31-
mechanism: { type: 'auto.function.tanstackstart', handled: false },
31+
mechanism: { type: 'auto.middleware.tanstackstart.request', handled: false },
3232
});
3333
});
3434

@@ -48,6 +48,23 @@ describe('sentryGlobalRequestMiddleware', () => {
4848
});
4949

5050
describe('sentryGlobalFunctionMiddleware', () => {
51+
afterEach(() => {
52+
vi.clearAllMocks();
53+
});
54+
55+
it('captures error with correct mechanism when next() throws', async () => {
56+
const error = new Error('test error');
57+
const next = vi.fn().mockRejectedValue(error);
58+
59+
const serverFn = sentryGlobalFunctionMiddleware.options.server!;
60+
61+
await expect(serverFn({ next })).rejects.toThrow('test error');
62+
63+
expect(captureExceptionSpy).toHaveBeenCalledWith(error, {
64+
mechanism: { type: 'auto.middleware.tanstackstart.server_function', handled: false },
65+
});
66+
});
67+
5168
it('has __SENTRY_INTERNAL__ flag set', () => {
5269
expect((sentryGlobalFunctionMiddleware as unknown as Record<string, unknown>)['__SENTRY_INTERNAL__']).toBe(true);
5370
});

0 commit comments

Comments
 (0)