diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3-dynamic-import/tests/errors.client.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-3-dynamic-import/tests/errors.client.test.ts index f4ca86413598..123b6f9a332a 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-3-dynamic-import/tests/errors.client.test.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-3-dynamic-import/tests/errors.client.test.ts @@ -21,6 +21,7 @@ test.describe('client-side errors', async () => { value: 'Error thrown from Nuxt-3 E2E test app', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], @@ -49,6 +50,7 @@ test.describe('client-side errors', async () => { value: 'Error thrown from Param Route Button', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], @@ -82,6 +84,7 @@ test.describe('client-side errors', async () => { value: 'Error thrown from Nuxt-3 E2E test app', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], @@ -96,6 +99,7 @@ test.describe('client-side errors', async () => { value: 'Another Error thrown from Nuxt-3 E2E test app', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3-dynamic-import/tests/errors.server.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-3-dynamic-import/tests/errors.server.test.ts index b18da9ba0a3b..53d89e5b937f 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-3-dynamic-import/tests/errors.server.test.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-3-dynamic-import/tests/errors.server.test.ts @@ -14,10 +14,23 @@ test.describe('server-side errors', async () => { 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); + const exception0 = error.exception.values[0]; + const exception1 = error.exception.values[1]; + + expect(exception0.type).toEqual('Error'); + expect(exception0.value).toEqual('Nuxt 3 Server error'); + expect(exception0.mechanism).toEqual({ + handled: false, + type: 'auto.function.nuxt.nitro', + exception_id: 1, + parent_id: 0, + source: 'cause', + }); + + expect(exception1.type).toEqual('Error'); + expect(exception1.value).toEqual('Nuxt 3 Server error'); + // TODO: This isn't correct but requires adjustment in the core SDK + expect(exception1.mechanism).toEqual({ handled: true, type: 'generic', exception_id: 0 }); }); test('captures api fetch error (fetched on click) with parametrized route', async ({ page }) => { @@ -32,9 +45,22 @@ test.describe('server-side errors', async () => { 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); + const exception0 = error.exception.values[0]; + const exception1 = error.exception.values[1]; + + expect(exception0.type).toEqual('Error'); + expect(exception0.value).toEqual('Nuxt 3 Param Server error'); + expect(exception0.mechanism).toEqual({ + handled: false, + type: 'auto.function.nuxt.nitro', + exception_id: 1, + parent_id: 0, + source: 'cause', + }); + + expect(exception1.type).toEqual('Error'); + expect(exception1.value).toEqual('Nuxt 3 Param Server error'); + // TODO: This isn't correct but requires adjustment in the core SDK + expect(exception1.mechanism).toEqual({ handled: true, type: 'generic', exception_id: 0 }); }); }); diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3-min/tests/errors.client.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-3-min/tests/errors.client.test.ts index 0de0c3dd498a..e9ef67ef75b6 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-3-min/tests/errors.client.test.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-3-min/tests/errors.client.test.ts @@ -21,6 +21,7 @@ test.describe('client-side errors', async () => { value: 'Error thrown from Nuxt-3-min E2E test app', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], @@ -49,6 +50,7 @@ test.describe('client-side errors', async () => { value: 'Error thrown from Param Route Button', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], @@ -82,6 +84,7 @@ test.describe('client-side errors', async () => { value: 'Error thrown from Nuxt-3-min E2E test app', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], @@ -96,6 +99,7 @@ test.describe('client-side errors', async () => { value: 'Another Error thrown from Nuxt-3-min E2E test app', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3-min/tests/errors.server.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-3-min/tests/errors.server.test.ts index 40904b51b993..8b182fec69c7 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-3-min/tests/errors.server.test.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-3-min/tests/errors.server.test.ts @@ -14,10 +14,23 @@ test.describe('server-side errors', async () => { 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); + const exception0 = error.exception.values[0]; + const exception1 = error.exception.values[1]; + + expect(exception0.type).toEqual('Error'); + expect(exception0.value).toEqual('Nuxt 3 Server error'); + expect(exception0.mechanism).toEqual({ + handled: false, + type: 'auto.function.nuxt.nitro', + exception_id: 1, + parent_id: 0, + source: 'cause', + }); + + // TODO: This isn't correct but requires adjustment in the core SDK + expect(exception1.type).toEqual('Error'); + expect(exception1.value).toEqual('Nuxt 3 Server error'); + expect(exception1.mechanism).toEqual({ handled: true, type: 'generic', exception_id: 0 }); }); test('captures api fetch error (fetched on click) with parametrized route', async ({ page }) => { @@ -32,9 +45,22 @@ test.describe('server-side errors', async () => { 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); + const exception0 = error.exception.values[0]; + const exception1 = error.exception.values[1]; + + expect(exception0.type).toEqual('Error'); + expect(exception0.value).toEqual('Nuxt 3 Param Server error'); + expect(exception0.mechanism).toEqual({ + handled: false, + type: 'auto.function.nuxt.nitro', + exception_id: 1, + parent_id: 0, + source: 'cause', + }); + + // TODO: This isn't correct but requires adjustment in the core SDK + expect(exception1.type).toEqual('Error'); + expect(exception1.value).toEqual('Nuxt 3 Param Server error'); + expect(exception1.mechanism).toEqual({ handled: true, type: 'generic', exception_id: 0 }); }); }); diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3-top-level-import/tests/errors.client.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-3-top-level-import/tests/errors.client.test.ts index 445a62e54b2a..ff99eb1b192f 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-3-top-level-import/tests/errors.client.test.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-3-top-level-import/tests/errors.client.test.ts @@ -21,6 +21,7 @@ test.describe('client-side errors', async () => { value: 'Error thrown from Nuxt-3 E2E test app', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], @@ -49,6 +50,7 @@ test.describe('client-side errors', async () => { value: 'Error thrown from Param Route Button', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], @@ -82,6 +84,7 @@ test.describe('client-side errors', async () => { value: 'Error thrown from Nuxt-3 E2E test app', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], @@ -96,6 +99,7 @@ test.describe('client-side errors', async () => { value: 'Another Error thrown from Nuxt-3 E2E test app', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3-top-level-import/tests/errors.server.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-3-top-level-import/tests/errors.server.test.ts index 551a33ee1fc1..d7aafde49d55 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-3-top-level-import/tests/errors.server.test.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-3-top-level-import/tests/errors.server.test.ts @@ -19,10 +19,23 @@ test.describe('server-side errors', async () => { 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); + const exception0 = error.exception.values[0]; + const exception1 = error.exception.values[1]; + + expect(exception0.type).toEqual('Error'); + expect(exception0.value).toEqual('Nuxt 3 Server error'); + expect(exception0.mechanism).toEqual({ + handled: false, + type: 'auto.function.nuxt.nitro', + exception_id: 1, + parent_id: 0, + source: 'cause', + }); + + expect(exception1.type).toEqual('Error'); + expect(exception1.value).toEqual('Nuxt 3 Server error'); + // TODO: This isn't correct but requires adjustment in the core SDK + expect(exception1.mechanism).toEqual({ handled: true, type: 'generic', exception_id: 0 }); expect(error.tags?.['my-isolated-tag']).toBe(true); expect(error.tags?.['my-global-scope-isolated-tag']).not.toBeDefined(); @@ -63,9 +76,22 @@ test.describe('server-side errors', async () => { 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); + const exception0 = error.exception.values[0]; + const exception1 = error.exception.values[1]; + + expect(exception0.type).toEqual('Error'); + expect(exception0.value).toEqual('Nuxt 3 Param Server error'); + expect(exception0.mechanism).toEqual({ + handled: false, + type: 'auto.function.nuxt.nitro', + exception_id: 1, + parent_id: 0, + source: 'cause', + }); + + expect(exception1.type).toEqual('Error'); + expect(exception1.value).toEqual('Nuxt 3 Param Server error'); + // TODO: This isn't correct but requires adjustment in the core SDK + expect(exception1.mechanism).toEqual({ handled: true, type: 'generic', exception_id: 0 }); }); }); diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3/tests/errors.client.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-3/tests/errors.client.test.ts index d94f649f78d1..11e4a5a367d4 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-3/tests/errors.client.test.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-3/tests/errors.client.test.ts @@ -21,6 +21,7 @@ test.describe('client-side errors', async () => { value: 'Error thrown from Nuxt-3 E2E test app', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], @@ -62,6 +63,7 @@ test.describe('client-side errors', async () => { value: 'Error thrown in Error Boundary', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], @@ -90,6 +92,7 @@ test.describe('client-side errors', async () => { value: 'Error thrown from Param Route Button', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], @@ -123,6 +126,7 @@ test.describe('client-side errors', async () => { value: 'Error thrown from Nuxt-3 E2E test app', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], @@ -137,6 +141,7 @@ test.describe('client-side errors', async () => { value: 'Another Error thrown from Nuxt-3 E2E test app', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], 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 index b62654b60c47..338ee6e3f78a 100644 --- 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 @@ -14,10 +14,23 @@ test.describe('server-side errors', async () => { 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); + const exception0 = error.exception.values[0]; + const exception1 = error.exception.values[1]; + + expect(exception0.type).toEqual('Error'); + expect(exception0.value).toEqual('Nuxt 3 Server error'); + expect(exception0.mechanism).toEqual({ + handled: false, + type: 'chained', + exception_id: 1, + parent_id: 0, + source: 'cause', + }); + + expect(exception1.type).toEqual('Error'); + expect(exception1.value).toEqual('Nuxt 3 Server error'); + // TODO: This isn't correct but requires adjustment in the core SDK + expect(exception1.mechanism).toEqual({ handled: true, type: 'generic', exception_id: 0 }); }); test('captures api fetch error (fetched on click) with parametrized route', async ({ page }) => { @@ -32,9 +45,22 @@ test.describe('server-side errors', async () => { 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); + const exception0 = error.exception.values[0]; + const exception1 = error.exception.values[1]; + + expect(exception0.type).toEqual('Error'); + expect(exception0.value).toEqual('Nuxt 3 Param Server error'); + expect(exception0.mechanism).toEqual({ + handled: false, + type: 'chained', + exception_id: 1, + parent_id: 0, + source: 'cause', + }); + + expect(exception1.type).toEqual('Error'); + expect(exception1.value).toEqual('Nuxt 3 Param Server error'); + // TODO: This isn't correct but requires adjustment in the core SDK + expect(exception1.mechanism).toEqual({ handled: true, type: 'generic', exception_id: 0 }); }); }); diff --git a/dev-packages/e2e-tests/test-applications/nuxt-4/tests/errors.client.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-4/tests/errors.client.test.ts index 6694ae851df1..2aed77dbfed6 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-4/tests/errors.client.test.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-4/tests/errors.client.test.ts @@ -21,6 +21,7 @@ test.describe('client-side errors', async () => { value: 'Error thrown from Nuxt-4 E2E test app', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], @@ -62,6 +63,7 @@ test.describe('client-side errors', async () => { value: 'Error thrown in Error Boundary', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], @@ -90,6 +92,7 @@ test.describe('client-side errors', async () => { value: 'Error thrown from Param Route Button', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], @@ -123,6 +126,7 @@ test.describe('client-side errors', async () => { value: 'Error thrown from Nuxt-4 E2E test app', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], @@ -137,6 +141,7 @@ test.describe('client-side errors', async () => { value: 'Another Error thrown from Nuxt-4 E2E test app', mechanism: { handled: false, + type: 'auto.function.nuxt.vue-error', }, }, ], diff --git a/dev-packages/e2e-tests/test-applications/nuxt-4/tests/errors.server.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-4/tests/errors.server.test.ts index 1d593cb09caf..62933f29dd48 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-4/tests/errors.server.test.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-4/tests/errors.server.test.ts @@ -14,10 +14,23 @@ test.describe('server-side errors', async () => { expect(error.transaction).toEqual('GET /api/server-error'); - const exception = error.exception.values[0]; - expect(exception.type).toEqual('Error'); - expect(exception.value).toEqual('Nuxt 4 Server error'); - expect(exception.mechanism.handled).toBe(false); + const exception0 = error.exception.values[0]; + const exception1 = error.exception.values[1]; + + expect(exception0.type).toEqual('Error'); + expect(exception0.value).toEqual('Nuxt 4 Server error'); + expect(exception0.mechanism).toEqual({ + handled: false, + type: 'auto.function.nuxt.nitro', + exception_id: 1, + parent_id: 0, + source: 'cause', + }); + + expect(exception1.type).toEqual('Error'); + expect(exception1.value).toEqual('Nuxt 4 Server error'); + // TODO: This isn't correct but requires adjustment in the core SDK + expect(exception1.mechanism).toEqual({ handled: true, type: 'generic', exception_id: 0 }); }); test('captures api fetch error (fetched on click) with parametrized route', async ({ page }) => { @@ -32,9 +45,22 @@ test.describe('server-side errors', async () => { 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 4 Param Server error'); - expect(exception.mechanism.handled).toBe(false); + const exception0 = error.exception.values[0]; + const exception1 = error.exception.values[1]; + + expect(exception0.type).toEqual('Error'); + expect(exception0.value).toEqual('Nuxt 4 Param Server error'); + expect(exception0.mechanism).toEqual({ + handled: false, + type: 'auto.function.nuxt.nitro', + exception_id: 1, + parent_id: 0, + source: 'cause', + }); + + expect(exception1.type).toEqual('Error'); + expect(exception1.value).toEqual('Nuxt 4 Param Server error'); + // TODO: This isn't correct but requires adjustment in the core SDK + expect(exception1.mechanism).toEqual({ handled: true, type: 'generic', exception_id: 0 }); }); }); diff --git a/packages/nuxt/src/runtime/hooks/captureErrorHook.ts b/packages/nuxt/src/runtime/hooks/captureErrorHook.ts index 7a27b7e6e4c6..9c2bc1011277 100644 --- a/packages/nuxt/src/runtime/hooks/captureErrorHook.ts +++ b/packages/nuxt/src/runtime/hooks/captureErrorHook.ts @@ -40,7 +40,7 @@ export async function sentryCaptureErrorHook(error: Error, errorContext: Capture captureException(error, { captureContext: { contexts: { nuxt: structuredContext } }, - mechanism: { handled: false }, + mechanism: { handled: false, type: 'auto.function.nuxt.nitro' }, }); await flushIfServerless(); diff --git a/packages/nuxt/src/runtime/utils.ts b/packages/nuxt/src/runtime/utils.ts index 29abbe23ec62..ce8069c58cdb 100644 --- a/packages/nuxt/src/runtime/utils.ts +++ b/packages/nuxt/src/runtime/utils.ts @@ -81,7 +81,7 @@ export function reportNuxtError(options: { setTimeout(() => { captureException(error, { captureContext: { contexts: { nuxt: metadata } }, - mechanism: { handled: false }, + mechanism: { handled: false, type: `auto.function.nuxt.${instance ? 'vue' : 'app'}-error` }, }); }); } diff --git a/packages/nuxt/test/runtime/utils.test.ts b/packages/nuxt/test/runtime/utils.test.ts index 9c3dd568d67a..70226ee12c86 100644 --- a/packages/nuxt/test/runtime/utils.test.ts +++ b/packages/nuxt/test/runtime/utils.test.ts @@ -119,7 +119,7 @@ describe('reportNuxtError', () => { expect(captureException).toHaveBeenCalledWith(mockError, { captureContext: { contexts: { nuxt: { info: undefined } } }, - mechanism: { handled: false }, + mechanism: { handled: false, type: 'auto.function.nuxt.app-error' }, }); }); @@ -129,7 +129,7 @@ describe('reportNuxtError', () => { expect(captureException).toHaveBeenCalledWith(mockError, { captureContext: { contexts: { nuxt: { info: undefined, propsData: { foo: 'bar' } } } }, - mechanism: { handled: false }, + mechanism: { handled: false, type: 'auto.function.nuxt.vue-error' }, }); }); @@ -141,7 +141,7 @@ describe('reportNuxtError', () => { expect(captureException).toHaveBeenCalledWith(mockError, { captureContext: { contexts: { nuxt: { info: undefined } } }, - mechanism: { handled: false }, + mechanism: { handled: false, type: 'auto.function.nuxt.vue-error' }, }); }); @@ -151,7 +151,7 @@ describe('reportNuxtError', () => { expect(captureException).toHaveBeenCalledWith(mockError, { captureContext: { contexts: { nuxt: { info: 'Some info' } } }, - mechanism: { handled: false }, + mechanism: { handled: false, type: 'auto.function.nuxt.app-error' }, }); }); });