Skip to content

Commit

Permalink
feat(hapi): Update scope transactionName when handling request (#11448
Browse files Browse the repository at this point in the history
)

This PR updates the scope's `transactionName` in our Hapi error handler.
Conveniently, we can access the parameterized route within our Hapi
plugin, meaning we're not constrained by reading route info from a
potential non-recording span.
  • Loading branch information
Lms24 authored Apr 9, 2024
1 parent 6c8cdcd commit 1067868
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ const init = async () => {
},
});

server.route({
method: 'GET',
path: '/test-error/{id}',
handler: function (request) {
console.log('This is an error with id', request.params.id);
throw new Error(`This is an error with id ${request.params.id}`);
},
});

server.route({
method: 'GET',
path: '/test-failure',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,20 @@ test('Sends successful transactions to Sentry', async ({ baseURL }) => {
.toBe(200);
});

test('sends error with parameterized transaction name', async ({ baseURL }) => {
const errorEventPromise = waitForError('node-hapi-app', errorEvent => {
return errorEvent?.exception?.values?.[0]?.value === 'This is an error with id 123';
});

try {
await axios.get(`${baseURL}/test-error/123`);
} catch {}

const errorEvent = await errorEventPromise;

expect(errorEvent?.transaction).toBe('GET /test-error/{id}');
});

test('Sends parameterized transactions to Sentry', async ({ baseURL }) => {
const pageloadTransactionEventPromise = waitForTransaction('node-hapi-app', transactionEvent => {
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ const init = async () => {
},
});

server.route({
method: 'GET',
path: '/error/{id}',
handler: (_request, _h) => {
return new Error('Sentry Test Error');
},
});

server.route({
method: 'GET',
path: '/boom-error',
Expand Down
14 changes: 14 additions & 0 deletions dev-packages/node-integration-tests/suites/tracing/hapi/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,20 @@ describe('hapi auto-instrumentation', () => {
.makeRequest('get', '/error');
});

test('CJS - should assign parameterized transactionName to error.', done => {
createRunner(__dirname, 'scenario.js')
.expect({
event: {
...EXPECTED_ERROR_EVENT,
transaction: 'GET /error/{id}',
},
})
.ignore('transaction')
.expectError()
.start(done)
.makeRequest('get', '/error/123');
});

test('CJS - should handle returned Boom errors in routes.', done => {
createRunner(__dirname, 'scenario.js')
.expect({
Expand Down
14 changes: 14 additions & 0 deletions packages/node/src/integrations/tracing/hapi/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ import {
captureException,
defineIntegration,
getActiveSpan,
getDefaultIsolationScope,
getIsolationScope,
getRootSpan,
} from '@sentry/core';
import type { IntegrationFn } from '@sentry/types';
import { logger } from '@sentry/utils';
import { DEBUG_BUILD } from '../../../debug-build';
import type { Boom, RequestEvent, ResponseObject, Server } from './types';

const _hapiIntegration = (() => {
Expand Down Expand Up @@ -58,6 +62,16 @@ export const hapiErrorPlugin = {
const server = serverArg as unknown as Server;

server.events.on('request', (request, event) => {
if (getIsolationScope() !== getDefaultIsolationScope()) {
const route = request.route;
if (route && route.path) {
getIsolationScope().setTransactionName(`${route.method?.toUpperCase() || 'GET'} ${route.path}`);
}
} else {
DEBUG_BUILD &&
logger.warn('Isolation scope is still the default isolation scope - skipping setting transactionName');
}

const activeSpan = getActiveSpan();
const rootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;

Expand Down

0 comments on commit 1067868

Please sign in to comment.