diff --git a/packages/nextjs/src/common/_error.ts b/packages/nextjs/src/common/_error.ts index 1ddd5ea63e01..1f114494567b 100644 --- a/packages/nextjs/src/common/_error.ts +++ b/packages/nextjs/src/common/_error.ts @@ -1,5 +1,6 @@ import { captureException, getClient, withScope } from '@sentry/core'; import type { NextPageContext } from 'next'; +import { flushQueue } from './utils/responseEnd'; type ContextOrProps = { req?: NextPageContext['req']; @@ -9,12 +10,6 @@ type ContextOrProps = { statusCode?: number; }; -/** Platform-agnostic version of `flush` */ -function flush(timeout?: number): PromiseLike { - const client = getClient(); - return client ? client.flush(timeout) : Promise.resolve(false); -} - /** * Capture the exception passed by nextjs to the `_error` page, adding context data as appropriate. * @@ -60,5 +55,5 @@ export async function captureUnderscoreErrorException(contextOrProps: ContextOrP // In case this is being run as part of a serverless function (as is the case with the server half of nextjs apps // deployed to vercel), make sure the error gets sent to Sentry before the lambda exits. - await flush(2000); + await flushQueue(); } diff --git a/packages/nextjs/src/common/utils/edgeWrapperUtils.ts b/packages/nextjs/src/common/utils/edgeWrapperUtils.ts index 72dc2f142365..008f8629f3ab 100644 --- a/packages/nextjs/src/common/utils/edgeWrapperUtils.ts +++ b/packages/nextjs/src/common/utils/edgeWrapperUtils.ts @@ -10,6 +10,7 @@ import { import type { EdgeRouteHandler } from '../../edge/types'; import { DEBUG_BUILD } from '../debug-build'; +import { flushQueue } from './responseEnd'; /** * Wraps a function on the edge runtime with error and performance monitoring. @@ -97,7 +98,7 @@ export function withEdgeWrapping( } finally { span?.finish(); currentScope?.setSpan(prevSpan); - await flush(2000); + await flushQueue(); } }; } diff --git a/packages/nextjs/src/common/withServerActionInstrumentation.ts b/packages/nextjs/src/common/withServerActionInstrumentation.ts index dcc1c7d29382..eafcff7b9075 100644 --- a/packages/nextjs/src/common/withServerActionInstrumentation.ts +++ b/packages/nextjs/src/common/withServerActionInstrumentation.ts @@ -3,6 +3,7 @@ import { logger, tracingContextFromHeaders } from '@sentry/utils'; import { DEBUG_BUILD } from './debug-build'; import { platformSupportsStreaming } from './utils/platformSupportsStreaming'; +import { flushQueue } from './utils/responseEnd'; interface Options { formData?: FormData; @@ -118,11 +119,11 @@ async function withServerActionInstrumentationImplementation any>( if (!platformSupportsStreaming() || process.env.NEXT_RUNTIME === 'edge') { // 1. Edge tranpsort requires manual flushing // 2. Lambdas require manual flushing to prevent execution freeze before the event is sent - await flush(1000); + await flushQueue(); } } diff --git a/packages/nextjs/src/common/wrapServerComponentWithSentry.ts b/packages/nextjs/src/common/wrapServerComponentWithSentry.ts index beb17980de5e..dade931bf074 100644 --- a/packages/nextjs/src/common/wrapServerComponentWithSentry.ts +++ b/packages/nextjs/src/common/wrapServerComponentWithSentry.ts @@ -1,7 +1,6 @@ import { addTracingExtensions, captureException, - flush, getCurrentHub, runWithAsyncContext, startTransaction, @@ -10,6 +9,7 @@ import { tracingContextFromHeaders, winterCGHeadersToDict } from '@sentry/utils' import { isNotFoundNavigationError, isRedirectNavigationError } from '../common/nextNavigationErrorUtils'; import type { ServerComponentContext } from '../common/types'; +import { flushQueue } from './utils/responseEnd'; /** * Wraps an `app` directory server component with Sentry error instrumentation. @@ -85,28 +85,31 @@ export function wrapServerComponentWithSentry any> maybePromiseResult = originalFunction.apply(thisArg, args); } catch (e) { handleErrorCase(e); - void flush(); + void flushQueue(); throw e; } if (typeof maybePromiseResult === 'object' && maybePromiseResult !== null && 'then' in maybePromiseResult) { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - Promise.resolve(maybePromiseResult).then( - () => { - transaction.finish(); - }, - e => { - handleErrorCase(e); - }, - ); - void flush(); + Promise.resolve(maybePromiseResult) + .then( + () => { + transaction.finish(); + }, + e => { + handleErrorCase(e); + }, + ) + .finally(() => { + void flushQueue(); + }); // It is very important that we return the original promise here, because Next.js attaches various properties // to that promise and will throw if they are not on the returned value. return maybePromiseResult; } else { transaction.finish(); - void flush(); + void flushQueue(); return maybePromiseResult; } });