Skip to content

Commit 624ee81

Browse files
committed
feat(nuxt/nitro): Flush with waitUntil after response
1 parent 05a368f commit 624ee81

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

packages/nuxt/src/runtime/plugins/sentry.server.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as Sentry from '@sentry/node';
22
import { H3Error } from 'h3';
33
import { defineNitroPlugin } from 'nitropack/runtime';
44
import type { NuxtRenderHTMLContext } from 'nuxt/app';
5-
import { addSentryTracingMetaTags, extractErrorContext } from '../utils';
5+
import { addSentryTracingMetaTags, extractErrorContext, vercelWaitUntilAndFlush } from '../utils';
66

77
export default defineNitroPlugin(nitroApp => {
88
nitroApp.hooks.hook('error', (error, errorContext) => {
@@ -29,10 +29,16 @@ export default defineNitroPlugin(nitroApp => {
2929
captureContext: { contexts: { nuxt: structuredContext } },
3030
mechanism: { handled: false },
3131
});
32+
33+
vercelWaitUntilAndFlush();
3234
});
3335

3436
// @ts-expect-error - 'render:html' is a valid hook name in the Nuxt context
3537
nitroApp.hooks.hook('render:html', (html: NuxtRenderHTMLContext) => {
3638
addSentryTracingMetaTags(html.head);
3739
});
40+
41+
nitroApp.hooks.hook('request', () => {
42+
vercelWaitUntilAndFlush();
43+
});
3844
});

packages/nuxt/src/runtime/utils.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { captureException, getClient, getTraceMetaTags } from '@sentry/core';
1+
import { captureException, flush, getClient, getTraceMetaTags } from '@sentry/core';
22
import type { ClientOptions, Context } from '@sentry/types';
3-
import { dropUndefinedKeys } from '@sentry/utils';
3+
import { dropUndefinedKeys, logger, vercelWaitUntil } from '@sentry/utils';
44
import type { VueOptions } from '@sentry/vue/src/types';
55
import type { CapturedErrorContext } from 'nitropack';
66
import type { NuxtRenderHTMLContext } from 'nuxt/app';
@@ -80,3 +80,31 @@ export function reportNuxtError(options: {
8080
});
8181
});
8282
}
83+
84+
/**
85+
* Flushes pending Sentry events with a 2 seconds timeout and in a way that cannot create unhandled promise rejections.
86+
*
87+
*/
88+
export async function flushSafelyWithTimeout(isDebug: boolean): Promise<void> {
89+
try {
90+
isDebug && logger.log('Flushing events...');
91+
await flush(2000);
92+
isDebug && logger.log('Done flushing events');
93+
} catch (e) {
94+
isDebug && logger.log('Error while flushing events:\n', e);
95+
}
96+
}
97+
98+
/**
99+
* Utility function for the Nuxt module runtime function as we always have to get the client instance to get
100+
* the `debug` option (we cannot access BUILD_DEBUG in the module runtime).
101+
*
102+
* This function should be called when Nitro ends a request (so Vercel can wait).
103+
*/
104+
export function vercelWaitUntilAndFlush(): void {
105+
const sentryClient = getClient();
106+
107+
if (sentryClient) {
108+
vercelWaitUntil(flushSafelyWithTimeout(sentryClient.getOptions().debug || false));
109+
}
110+
}

0 commit comments

Comments
 (0)