-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(nextjs): Add
experimental_captureRequestError
for `onRequestEr…
…ror` hook (#12885)
- Loading branch information
Showing
10 changed files
with
169 additions
and
15 deletions.
There are no files selected for viewing
17 changes: 17 additions & 0 deletions
17
dev-packages/e2e-tests/test-applications/nextjs-15/app/nested-rsc-error/[param]/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { Suspense } from 'react'; | ||
|
||
export const dynamic = 'force-dynamic'; | ||
|
||
export default async function Page() { | ||
return ( | ||
<Suspense fallback={<p>Loading...</p>}> | ||
{/* @ts-ignore */} | ||
<Crash />; | ||
</Suspense> | ||
); | ||
} | ||
|
||
async function Crash() { | ||
throw new Error('I am technically uncatchable'); | ||
return <p>unreachable</p>; | ||
} |
8 changes: 8 additions & 0 deletions
8
...ges/e2e-tests/test-applications/nextjs-15/app/streaming-rsc-error/[param]/client-page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
'use client'; | ||
|
||
import { use } from 'react'; | ||
|
||
export function RenderPromise({ stringPromise }: { stringPromise: Promise<string> }) { | ||
const s = use(stringPromise); | ||
return <>{s}</>; | ||
} |
18 changes: 18 additions & 0 deletions
18
dev-packages/e2e-tests/test-applications/nextjs-15/app/streaming-rsc-error/[param]/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { Suspense } from 'react'; | ||
import { RenderPromise } from './client-page'; | ||
|
||
export const dynamic = 'force-dynamic'; | ||
|
||
export default async function Page() { | ||
const crashingPromise = new Promise<string>((_, reject) => { | ||
setTimeout(() => { | ||
reject(new Error('I am a data streaming error')); | ||
}, 100); | ||
}); | ||
|
||
return ( | ||
<Suspense fallback={<p>Loading...</p>}> | ||
<RenderPromise stringPromise={crashingPromise} />; | ||
</Suspense> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
dev-packages/e2e-tests/test-applications/nextjs-15/tests/nested-rsc-error.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { expect, test } from '@playwright/test'; | ||
import { waitForError, waitForTransaction } from '@sentry-internal/test-utils'; | ||
|
||
test('Should capture errors from nested server components when `Sentry.captureRequestError` is added to the `onRequestError` hook', async ({ | ||
page, | ||
}) => { | ||
const errorEventPromise = waitForError('nextjs-15', errorEvent => { | ||
return !!errorEvent?.exception?.values?.some(value => value.value === 'I am technically uncatchable'); | ||
}); | ||
|
||
const serverTransactionPromise = waitForTransaction('nextjs-15', async transactionEvent => { | ||
return transactionEvent?.transaction === 'GET /nested-rsc-error/[param]'; | ||
}); | ||
|
||
await page.goto(`/nested-rsc-error/123`); | ||
const errorEvent = await errorEventPromise; | ||
const serverTransactionEvent = await serverTransactionPromise; | ||
|
||
// error event is part of the transaction | ||
expect(errorEvent.contexts?.trace?.trace_id).toBe(serverTransactionEvent.contexts?.trace?.trace_id); | ||
|
||
expect(errorEvent.request).toMatchObject({ | ||
headers: expect.any(Object), | ||
method: 'GET', | ||
}); | ||
|
||
expect(errorEvent.contexts?.nextjs).toEqual({ | ||
route_type: 'render', | ||
router_kind: 'App Router', | ||
router_path: '/nested-rsc-error/[param]', | ||
request_path: '/nested-rsc-error/123', | ||
}); | ||
}); |
33 changes: 33 additions & 0 deletions
33
dev-packages/e2e-tests/test-applications/nextjs-15/tests/streaming-rsc-error.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { expect, test } from '@playwright/test'; | ||
import { waitForError, waitForTransaction } from '@sentry-internal/test-utils'; | ||
|
||
test('Should capture errors for crashing streaming promises in server components when `Sentry.captureRequestError` is added to the `onRequestError` hook', async ({ | ||
page, | ||
}) => { | ||
const errorEventPromise = waitForError('nextjs-15', errorEvent => { | ||
return !!errorEvent?.exception?.values?.some(value => value.value === 'I am a data streaming error'); | ||
}); | ||
|
||
const serverTransactionPromise = waitForTransaction('nextjs-15', async transactionEvent => { | ||
return transactionEvent?.transaction === 'GET /streaming-rsc-error/[param]'; | ||
}); | ||
|
||
await page.goto(`/streaming-rsc-error/123`); | ||
const errorEvent = await errorEventPromise; | ||
const serverTransactionEvent = await serverTransactionPromise; | ||
|
||
// error event is part of the transaction | ||
expect(errorEvent.contexts?.trace?.trace_id).toBe(serverTransactionEvent.contexts?.trace?.trace_id); | ||
|
||
expect(errorEvent.request).toMatchObject({ | ||
headers: expect.any(Object), | ||
method: 'GET', | ||
}); | ||
|
||
expect(errorEvent.contexts?.nextjs).toEqual({ | ||
route_type: 'render', | ||
router_kind: 'App Router', | ||
router_path: '/streaming-rsc-error/[param]', | ||
request_path: '/streaming-rsc-error/123', | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { captureException, withScope } from '@sentry/core'; | ||
|
||
type RequestInfo = { | ||
url: string; | ||
method: string; | ||
headers: Record<string, string | string[] | undefined>; | ||
}; | ||
|
||
type ErrorContext = { | ||
routerKind: string; // 'Pages Router' | 'App Router' | ||
routePath: string; | ||
routeType: string; // 'render' | 'route' | 'middleware' | ||
}; | ||
|
||
/** | ||
* Reports errors for the Next.js `onRequestError` instrumentation hook. | ||
* | ||
* Notice: This function is experimental and not intended for production use. Breaking changes may be done to this funtion in any release. | ||
* | ||
* @experimental | ||
*/ | ||
export function experimental_captureRequestError( | ||
error: unknown, | ||
request: RequestInfo, | ||
errorContext: ErrorContext, | ||
): void { | ||
withScope(scope => { | ||
scope.setSDKProcessingMetadata({ | ||
request: { | ||
headers: request.headers, | ||
method: request.method, | ||
}, | ||
}); | ||
|
||
scope.setContext('nextjs', { | ||
request_path: request.url, | ||
router_kind: errorContext.routerKind, | ||
router_path: errorContext.routePath, | ||
route_type: errorContext.routeType, | ||
}); | ||
|
||
scope.setTransactionName(errorContext.routePath); | ||
|
||
captureException(error, { | ||
mechanism: { | ||
handled: false, | ||
}, | ||
}); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,14 @@ | ||
export { wrapGetStaticPropsWithSentry } from './wrapGetStaticPropsWithSentry'; | ||
|
||
export { wrapGetInitialPropsWithSentry } from './wrapGetInitialPropsWithSentry'; | ||
|
||
export { wrapAppGetInitialPropsWithSentry } from './wrapAppGetInitialPropsWithSentry'; | ||
|
||
export { wrapDocumentGetInitialPropsWithSentry } from './wrapDocumentGetInitialPropsWithSentry'; | ||
|
||
export { wrapErrorGetInitialPropsWithSentry } from './wrapErrorGetInitialPropsWithSentry'; | ||
|
||
export { wrapGetServerSidePropsWithSentry } from './wrapGetServerSidePropsWithSentry'; | ||
|
||
export { wrapServerComponentWithSentry } from './wrapServerComponentWithSentry'; | ||
|
||
export { wrapRouteHandlerWithSentry } from './wrapRouteHandlerWithSentry'; | ||
|
||
export { wrapApiHandlerWithSentryVercelCrons } from './wrapApiHandlerWithSentryVercelCrons'; | ||
|
||
export { wrapMiddlewareWithSentry } from './wrapMiddlewareWithSentry'; | ||
|
||
export { wrapPageComponentWithSentry } from './wrapPageComponentWithSentry'; | ||
|
||
export { wrapGenerationFunctionWithSentry } from './wrapGenerationFunctionWithSentry'; | ||
|
||
export { withServerActionInstrumentation } from './withServerActionInstrumentation'; | ||
export { experimental_captureRequestError } from './captureRequestError'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters