Skip to content

Commit

Permalink
feat(nuxt/nitro): Flush with waitUntil after response
Browse files Browse the repository at this point in the history
  • Loading branch information
s1gr1d committed Oct 7, 2024
1 parent 05a368f commit 624ee81
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 3 deletions.
8 changes: 7 additions & 1 deletion packages/nuxt/src/runtime/plugins/sentry.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as Sentry from '@sentry/node';
import { H3Error } from 'h3';
import { defineNitroPlugin } from 'nitropack/runtime';
import type { NuxtRenderHTMLContext } from 'nuxt/app';
import { addSentryTracingMetaTags, extractErrorContext } from '../utils';
import { addSentryTracingMetaTags, extractErrorContext, vercelWaitUntilAndFlush } from '../utils';

export default defineNitroPlugin(nitroApp => {
nitroApp.hooks.hook('error', (error, errorContext) => {
Expand All @@ -29,10 +29,16 @@ export default defineNitroPlugin(nitroApp => {
captureContext: { contexts: { nuxt: structuredContext } },
mechanism: { handled: false },
});

vercelWaitUntilAndFlush();
});

// @ts-expect-error - 'render:html' is a valid hook name in the Nuxt context
nitroApp.hooks.hook('render:html', (html: NuxtRenderHTMLContext) => {
addSentryTracingMetaTags(html.head);
});

nitroApp.hooks.hook('request', () => {
vercelWaitUntilAndFlush();
});
});
32 changes: 30 additions & 2 deletions packages/nuxt/src/runtime/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { captureException, getClient, getTraceMetaTags } from '@sentry/core';
import { captureException, flush, getClient, getTraceMetaTags } from '@sentry/core';
import type { ClientOptions, Context } from '@sentry/types';
import { dropUndefinedKeys } from '@sentry/utils';
import { dropUndefinedKeys, logger, vercelWaitUntil } from '@sentry/utils';
import type { VueOptions } from '@sentry/vue/src/types';
import type { CapturedErrorContext } from 'nitropack';
import type { NuxtRenderHTMLContext } from 'nuxt/app';
Expand Down Expand Up @@ -80,3 +80,31 @@ export function reportNuxtError(options: {
});
});
}

/**
* Flushes pending Sentry events with a 2 seconds timeout and in a way that cannot create unhandled promise rejections.
*
*/
export async function flushSafelyWithTimeout(isDebug: boolean): Promise<void> {
try {
isDebug && logger.log('Flushing events...');
await flush(2000);
isDebug && logger.log('Done flushing events');
} catch (e) {
isDebug && logger.log('Error while flushing events:\n', e);
}
}

/**
* Utility function for the Nuxt module runtime function as we always have to get the client instance to get
* the `debug` option (we cannot access BUILD_DEBUG in the module runtime).
*
* This function should be called when Nitro ends a request (so Vercel can wait).
*/
export function vercelWaitUntilAndFlush(): void {
const sentryClient = getClient();

if (sentryClient) {
vercelWaitUntil(flushSafelyWithTimeout(sentryClient.getOptions().debug || false));
}
}

0 comments on commit 624ee81

Please sign in to comment.