From bd6ceac3c479b544e8b847a841bfcc57daf761cd Mon Sep 17 00:00:00 2001 From: s1gr1d Date: Fri, 9 Aug 2024 14:49:10 +0200 Subject: [PATCH 1/2] feat(nuxt): Set transaction name for server error --- .../test-applications/nuxt-3/app.vue | 4 ++ .../nuxt-3/pages/fetch-server-error.vue | 11 +++++ .../nuxt-3/pages/test-param/[param].vue | 11 +++++ .../nuxt-3/server/api/param-error/[param].ts | 3 ++ .../nuxt-3/server/api/server-error.ts | 3 ++ .../nuxt-3/server/api/test-param/[param].ts | 5 +++ .../nuxt-3/server/tsconfig.json | 3 ++ .../nuxt-3/tests/errors.server.test.ts | 40 +++++++++++++++++++ .../nuxt/src/runtime/plugins/sentry.server.ts | 12 +++++- 9 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 dev-packages/e2e-tests/test-applications/nuxt-3/pages/fetch-server-error.vue create mode 100644 dev-packages/e2e-tests/test-applications/nuxt-3/server/api/param-error/[param].ts create mode 100644 dev-packages/e2e-tests/test-applications/nuxt-3/server/api/server-error.ts create mode 100644 dev-packages/e2e-tests/test-applications/nuxt-3/server/api/test-param/[param].ts create mode 100644 dev-packages/e2e-tests/test-applications/nuxt-3/server/tsconfig.json create mode 100644 dev-packages/e2e-tests/test-applications/nuxt-3/tests/errors.server.test.ts diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3/app.vue b/dev-packages/e2e-tests/test-applications/nuxt-3/app.vue index 06f3020220dd..4e7954ceb4af 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-3/app.vue +++ b/dev-packages/e2e-tests/test-applications/nuxt-3/app.vue @@ -3,6 +3,8 @@
@@ -11,3 +13,5 @@ + diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3/pages/fetch-server-error.vue b/dev-packages/e2e-tests/test-applications/nuxt-3/pages/fetch-server-error.vue new file mode 100644 index 000000000000..4643f045582e --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/nuxt-3/pages/fetch-server-error.vue @@ -0,0 +1,11 @@ + + + \ No newline at end of file diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3/pages/test-param/[param].vue b/dev-packages/e2e-tests/test-applications/nuxt-3/pages/test-param/[param].vue index a9bb6177cb15..4b2b7e35a83e 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-3/pages/test-param/[param].vue +++ b/dev-packages/e2e-tests/test-applications/nuxt-3/pages/test-param/[param].vue @@ -1,4 +1,15 @@ + + diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3/server/api/param-error/[param].ts b/dev-packages/e2e-tests/test-applications/nuxt-3/server/api/param-error/[param].ts new file mode 100644 index 000000000000..3fa894e0896a --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/nuxt-3/server/api/param-error/[param].ts @@ -0,0 +1,3 @@ +export default defineEventHandler(_e => { + throw new Error('Nuxt 3 Param Server error'); +}); diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3/server/api/server-error.ts b/dev-packages/e2e-tests/test-applications/nuxt-3/server/api/server-error.ts new file mode 100644 index 000000000000..f8533bfab1e5 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/nuxt-3/server/api/server-error.ts @@ -0,0 +1,3 @@ +export default defineEventHandler(event => { + throw new Error('Nuxt 3 Server error'); +}); diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3/server/api/test-param/[param].ts b/dev-packages/e2e-tests/test-applications/nuxt-3/server/api/test-param/[param].ts new file mode 100644 index 000000000000..6e4674ee21a9 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/nuxt-3/server/api/test-param/[param].ts @@ -0,0 +1,5 @@ +export default defineEventHandler(event => { + const param = getRouterParam(event, 'param'); + + return `Param: ${param}!`; +}); diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3/server/tsconfig.json b/dev-packages/e2e-tests/test-applications/nuxt-3/server/tsconfig.json new file mode 100644 index 000000000000..b9ed69c19eaf --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/nuxt-3/server/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../.nuxt/tsconfig.server.json" +} diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3/tests/errors.server.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-3/tests/errors.server.test.ts new file mode 100644 index 000000000000..e9445d4c2382 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/nuxt-3/tests/errors.server.test.ts @@ -0,0 +1,40 @@ +import { expect, test } from '@playwright/test'; +import { waitForError } from '@sentry-internal/test-utils'; + +test.describe('server-side errors', async () => { + test('captures api fetch error (fetched on click)', async ({ page }) => { + const errorPromise = waitForError('nuxt-3', async errorEvent => { + return errorEvent?.exception?.values?.[0]?.value === 'Nuxt 3 Server error'; + }); + + await page.goto(`/fetch-server-error`); + await page.getByText('Fetch Server Data').click(); + + const error = await errorPromise; + + expect(error.transaction).toEqual('GET /api/server-error'); + + const exception = error.exception.values[0]; + expect(exception.type).toEqual('Error'); + expect(exception.value).toEqual('Nuxt 3 Server error'); + expect(exception.mechanism.handled).toBe(false); + }); + + test('captures api fetch error (fetched on click) with parametrized route', async ({ page }) => { + const errorPromise = waitForError('nuxt-3', async errorEvent => { + return errorEvent?.exception?.values?.[0]?.value === 'Nuxt 3 Param Server error'; + }); + + await page.goto(`/test-param/1234`); + await page.getByText('Fetch Server Data').click(); + + const error = await errorPromise; + + expect(error.transaction).toEqual('GET /api/param-error/1234'); + + const exception = error.exception.values[0]; + expect(exception.type).toEqual('Error'); + expect(exception.value).toEqual('Nuxt 3 Param Server error'); + expect(exception.mechanism.handled).toBe(false); + }); +}); diff --git a/packages/nuxt/src/runtime/plugins/sentry.server.ts b/packages/nuxt/src/runtime/plugins/sentry.server.ts index 476037ac980b..00d18456f40e 100644 --- a/packages/nuxt/src/runtime/plugins/sentry.server.ts +++ b/packages/nuxt/src/runtime/plugins/sentry.server.ts @@ -1,4 +1,4 @@ -import { captureException } from '@sentry/node'; +import * as Sentry from '@sentry/node'; import { H3Error } from 'h3'; import { defineNitroPlugin } from 'nitropack/runtime'; import type { NuxtRenderHTMLContext } from 'nuxt/app'; @@ -14,9 +14,17 @@ export default defineNitroPlugin(nitroApp => { } } + const currentScope = Sentry.getCurrentScope(); + + const { method, path } = { + method: errorContext.event && errorContext.event._method ? errorContext.event._method : '', + path: errorContext.event && errorContext.event._path ? errorContext.event._path : 'unknown-path', + }; + currentScope.setTransactionName(`${method} ${path}`); + const structuredContext = extractErrorContext(errorContext); - captureException(error, { + Sentry.captureException(error, { captureContext: { contexts: { nuxt: structuredContext } }, mechanism: { handled: false }, }); From cb53af34f313a6f6cb51564b7db3f7444e8812b9 Mon Sep 17 00:00:00 2001 From: s1gr1d Date: Mon, 12 Aug 2024 11:47:55 +0200 Subject: [PATCH 2/2] review changes --- packages/nuxt/src/runtime/plugins/sentry.server.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/nuxt/src/runtime/plugins/sentry.server.ts b/packages/nuxt/src/runtime/plugins/sentry.server.ts index 00d18456f40e..1159a6d427ff 100644 --- a/packages/nuxt/src/runtime/plugins/sentry.server.ts +++ b/packages/nuxt/src/runtime/plugins/sentry.server.ts @@ -14,13 +14,14 @@ export default defineNitroPlugin(nitroApp => { } } - const currentScope = Sentry.getCurrentScope(); - const { method, path } = { method: errorContext.event && errorContext.event._method ? errorContext.event._method : '', - path: errorContext.event && errorContext.event._path ? errorContext.event._path : 'unknown-path', + path: errorContext.event && errorContext.event._path ? errorContext.event._path : null, }; - currentScope.setTransactionName(`${method} ${path}`); + + if (path) { + Sentry.getCurrentScope().setTransactionName(`${method} ${path}`); + } const structuredContext = extractErrorContext(errorContext);