-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(node): Support Express v5 (#15380)
The goal is for Express to eventually support publishing events to `diagnostics_channel` (#15107) so that Open Telemetry can instrument it without monkey-patching internal code. However, this might take a while and it would be great to support Express v5 now. This PR is a stop-gap solution until that work is complete and published. This PR vendors the code added in my otel PR: - open-telemetry/opentelemetry-js-contrib#2437 - Adds a new instrumentation specifically for hooking express v5 - Copies the Express v4 integration tests to test v5 - The only changes in the tests is the removal of a couple of complex regex tests where the regexes are no longer supported by Express. - Modifies the NestJs v11 tests which now support full Express spans
- Loading branch information
Showing
68 changed files
with
3,166 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
dev-packages/node-integration-tests/suites/express-v5/handle-error-scope-data-loss/server.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { loggingTransport } from '@sentry-internal/node-integration-tests'; | ||
import * as Sentry from '@sentry/node'; | ||
|
||
Sentry.init({ | ||
dsn: 'https://[email protected]/1337', | ||
release: '1.0', | ||
transport: loggingTransport, | ||
}); | ||
|
||
import { startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests'; | ||
import express from 'express'; | ||
|
||
const app = express(); | ||
|
||
Sentry.setTag('global', 'tag'); | ||
|
||
app.get('/test/withScope', () => { | ||
Sentry.withScope(scope => { | ||
scope.setTag('local', 'tag'); | ||
throw new Error('test_error'); | ||
}); | ||
}); | ||
|
||
app.get('/test/isolationScope', () => { | ||
Sentry.getIsolationScope().setTag('isolation-scope', 'tag'); | ||
throw new Error('isolation_test_error'); | ||
}); | ||
|
||
Sentry.setupExpressErrorHandler(app); | ||
|
||
startExpressServerAndSendPortToRunner(app); |
85 changes: 85 additions & 0 deletions
85
dev-packages/node-integration-tests/suites/express-v5/handle-error-scope-data-loss/test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { cleanupChildProcesses, createRunner } from '../../../utils/runner'; | ||
|
||
afterAll(() => { | ||
cleanupChildProcesses(); | ||
}); | ||
|
||
/** | ||
* Why does this test exist? | ||
* | ||
* We recently discovered that errors caught by global handlers will potentially loose scope data from the active scope | ||
* where the error was originally thrown in. The simple example in this test (see subject.ts) demonstrates this behavior | ||
* (in a Node environment but the same behavior applies to the browser; see the test there). | ||
* | ||
* This test nevertheless covers the behavior so that we're aware. | ||
*/ | ||
test('withScope scope is NOT applied to thrown error caught by global handler', done => { | ||
createRunner(__dirname, 'server.ts') | ||
.expect({ | ||
event: { | ||
exception: { | ||
values: [ | ||
{ | ||
mechanism: { | ||
type: 'middleware', | ||
handled: false, | ||
}, | ||
type: 'Error', | ||
value: 'test_error', | ||
stacktrace: { | ||
frames: expect.arrayContaining([ | ||
expect.objectContaining({ | ||
function: expect.any(String), | ||
lineno: expect.any(Number), | ||
colno: expect.any(Number), | ||
}), | ||
]), | ||
}, | ||
}, | ||
], | ||
}, | ||
// 'local' tag is not applied to the event | ||
tags: expect.not.objectContaining({ local: expect.anything() }), | ||
}, | ||
}) | ||
.start(done) | ||
.makeRequest('get', '/test/withScope', { expectError: true }); | ||
}); | ||
|
||
/** | ||
* This test shows that the isolation scope set tags are applied correctly to the error. | ||
*/ | ||
test('isolation scope is applied to thrown error caught by global handler', done => { | ||
createRunner(__dirname, 'server.ts') | ||
.expect({ | ||
event: { | ||
exception: { | ||
values: [ | ||
{ | ||
mechanism: { | ||
type: 'middleware', | ||
handled: false, | ||
}, | ||
type: 'Error', | ||
value: 'isolation_test_error', | ||
stacktrace: { | ||
frames: expect.arrayContaining([ | ||
expect.objectContaining({ | ||
function: expect.any(String), | ||
lineno: expect.any(Number), | ||
colno: expect.any(Number), | ||
}), | ||
]), | ||
}, | ||
}, | ||
], | ||
}, | ||
tags: { | ||
global: 'tag', | ||
'isolation-scope': 'tag', | ||
}, | ||
}, | ||
}) | ||
.start(done) | ||
.makeRequest('get', '/test/isolationScope', { expectError: true }); | ||
}); |
22 changes: 22 additions & 0 deletions
22
...ckages/node-integration-tests/suites/express-v5/handle-error-tracesSampleRate-0/server.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { loggingTransport } from '@sentry-internal/node-integration-tests'; | ||
import * as Sentry from '@sentry/node'; | ||
|
||
Sentry.init({ | ||
dsn: 'https://[email protected]/1337', | ||
release: '1.0', | ||
transport: loggingTransport, | ||
tracesSampleRate: 1, | ||
}); | ||
|
||
import { startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests'; | ||
import express from 'express'; | ||
|
||
const app = express(); | ||
|
||
app.get('/test/express/:id', req => { | ||
throw new Error(`test_error with id ${req.params.id}`); | ||
}); | ||
|
||
Sentry.setupExpressErrorHandler(app); | ||
|
||
startExpressServerAndSendPortToRunner(app); |
38 changes: 38 additions & 0 deletions
38
...packages/node-integration-tests/suites/express-v5/handle-error-tracesSampleRate-0/test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { cleanupChildProcesses, createRunner } from '../../../utils/runner'; | ||
|
||
afterAll(() => { | ||
cleanupChildProcesses(); | ||
}); | ||
|
||
test('should capture and send Express controller error with txn name if tracesSampleRate is 0', done => { | ||
createRunner(__dirname, 'server.ts') | ||
.ignore('transaction') | ||
.expect({ | ||
event: { | ||
exception: { | ||
values: [ | ||
{ | ||
mechanism: { | ||
type: 'middleware', | ||
handled: false, | ||
}, | ||
type: 'Error', | ||
value: 'test_error with id 123', | ||
stacktrace: { | ||
frames: expect.arrayContaining([ | ||
expect.objectContaining({ | ||
function: expect.any(String), | ||
lineno: expect.any(Number), | ||
colno: expect.any(Number), | ||
}), | ||
]), | ||
}, | ||
}, | ||
], | ||
}, | ||
transaction: 'GET /test/express/:id', | ||
}, | ||
}) | ||
.start(done) | ||
.makeRequest('get', '/test/express/123', { expectError: true }); | ||
}); |
21 changes: 21 additions & 0 deletions
21
...es/node-integration-tests/suites/express-v5/handle-error-tracesSampleRate-unset/server.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { loggingTransport } from '@sentry-internal/node-integration-tests'; | ||
import * as Sentry from '@sentry/node'; | ||
|
||
Sentry.init({ | ||
dsn: 'https://[email protected]/1337', | ||
release: '1.0', | ||
transport: loggingTransport, | ||
}); | ||
|
||
import { startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests'; | ||
import express from 'express'; | ||
|
||
const app = express(); | ||
|
||
app.get('/test/express/:id', req => { | ||
throw new Error(`test_error with id ${req.params.id}`); | ||
}); | ||
|
||
Sentry.setupExpressErrorHandler(app); | ||
|
||
startExpressServerAndSendPortToRunner(app); |
37 changes: 37 additions & 0 deletions
37
...ages/node-integration-tests/suites/express-v5/handle-error-tracesSampleRate-unset/test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { cleanupChildProcesses, createRunner } from '../../../utils/runner'; | ||
|
||
afterAll(() => { | ||
cleanupChildProcesses(); | ||
}); | ||
|
||
test('should capture and send Express controller error if tracesSampleRate is not set.', done => { | ||
createRunner(__dirname, 'server.ts') | ||
.ignore('transaction') | ||
.expect({ | ||
event: { | ||
exception: { | ||
values: [ | ||
{ | ||
mechanism: { | ||
type: 'middleware', | ||
handled: false, | ||
}, | ||
type: 'Error', | ||
value: 'test_error with id 123', | ||
stacktrace: { | ||
frames: expect.arrayContaining([ | ||
expect.objectContaining({ | ||
function: expect.any(String), | ||
lineno: expect.any(Number), | ||
colno: expect.any(Number), | ||
}), | ||
]), | ||
}, | ||
}, | ||
], | ||
}, | ||
}, | ||
}) | ||
.start(done) | ||
.makeRequest('get', '/test/express/123', { expectError: true }); | ||
}); |
Oops, something went wrong.