-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
ref(node): Streamline vendored fs instrumentation #21532
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| import * as Sentry from '@sentry/node'; | ||
| import { loggingTransport, startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests'; | ||
|
|
||
| Sentry.init({ | ||
| dsn: 'https://public@dsn.ingest.sentry.io/1337', | ||
| release: '1.0', | ||
| transport: loggingTransport, | ||
| tracesSampleRate: 1, | ||
| integrations: [ | ||
| // Only record error messages - file paths must NOT be recorded | ||
| Sentry.fsIntegration({ | ||
| recordErrorMessagesAsSpanAttributes: true, | ||
| }), | ||
| ], | ||
| }); | ||
|
|
||
| import express from 'express'; | ||
| import * as fs from 'fs'; | ||
| import * as path from 'path'; | ||
|
|
||
| const app = express(); | ||
|
|
||
| app.get('/readFile', async (_, res) => { | ||
| await fs.promises.readFile(path.join(__dirname, 'fixtures', 'some-file.txt'), 'utf-8'); | ||
| res.send('done'); | ||
| }); | ||
|
|
||
| app.get('/readFile-error', async (_, res) => { | ||
| try { | ||
| await fs.promises.readFile(path.join(__dirname, 'fixtures', 'some-file-that-doesnt-exist.txt'), 'utf-8'); | ||
| } catch { | ||
| // noop | ||
| } | ||
| res.send('done'); | ||
| }); | ||
|
mydea marked this conversation as resolved.
Dismissed
|
||
|
|
||
| Sentry.setupExpressErrorHandler(app); | ||
|
|
||
| startExpressServerAndSendPortToRunner(app); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| import * as Sentry from '@sentry/node'; | ||
| import { loggingTransport, startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests'; | ||
|
|
||
| Sentry.init({ | ||
| dsn: 'https://public@dsn.ingest.sentry.io/1337', | ||
| release: '1.0', | ||
| transport: loggingTransport, | ||
| tracesSampleRate: 1, | ||
| integrations: [ | ||
| // Only record file paths - error messages must NOT be recorded | ||
| Sentry.fsIntegration({ | ||
| recordFilePaths: true, | ||
| }), | ||
| ], | ||
| }); | ||
|
|
||
| import express from 'express'; | ||
| import * as fs from 'fs'; | ||
| import * as path from 'path'; | ||
|
|
||
| const app = express(); | ||
|
|
||
| app.get('/readFile', async (_, res) => { | ||
| await fs.promises.readFile(path.join(__dirname, 'fixtures', 'some-file.txt'), 'utf-8'); | ||
| res.send('done'); | ||
| }); | ||
|
mydea marked this conversation as resolved.
Dismissed
|
||
|
|
||
| app.get('/readFile-error', async (_, res) => { | ||
| try { | ||
| await fs.promises.readFile(path.join(__dirname, 'fixtures', 'some-file-that-doesnt-exist.txt'), 'utf-8'); | ||
| } catch { | ||
| // noop | ||
| } | ||
| res.send('done'); | ||
| }); | ||
|
mydea marked this conversation as resolved.
Dismissed
|
||
|
|
||
| Sentry.setupExpressErrorHandler(app); | ||
|
|
||
| startExpressServerAndSendPortToRunner(app); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -271,3 +271,83 @@ test('should create spans for fs operations that take target argument', async () | |
| expect(result).toEqual('done'); | ||
| await runner.completed(); | ||
| }); | ||
|
|
||
| test('records file path but not error messages when only `recordFilePaths` is enabled', async () => { | ||
| const runner = createRunner(__dirname, 'server-record-paths-only.ts') | ||
| .expect({ | ||
| transaction: { | ||
| transaction: 'GET /readFile-error', | ||
| spans: expect.arrayContaining([ | ||
| expect.objectContaining({ | ||
| description: 'fs.readFile', | ||
| op: 'file', | ||
| status: 'internal_error', | ||
| // `path_argument` is recorded, but `fs_error` is NOT, since `recordErrorMessagesAsSpanAttributes` is off | ||
| data: { | ||
| path_argument: expect.stringMatching('/fixtures/some-file-that-doesnt-exist.txt'), | ||
| [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', | ||
| [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', | ||
| }, | ||
| }), | ||
| ]), | ||
| }, | ||
| }) | ||
| .start(); | ||
|
|
||
| const result = await runner.makeRequest('get', '/readFile-error'); | ||
| expect(result).toEqual('done'); | ||
| await runner.completed(); | ||
| }); | ||
|
|
||
| test('records error messages but not file paths when only `recordErrorMessagesAsSpanAttributes` is enabled', async () => { | ||
| const runner = createRunner(__dirname, 'server-record-errors-only.ts') | ||
| .expect({ | ||
| transaction: { | ||
| transaction: 'GET /readFile-error', | ||
| spans: expect.arrayContaining([ | ||
| expect.objectContaining({ | ||
| description: 'fs.readFile', | ||
| op: 'file', | ||
| status: 'internal_error', | ||
| // `fs_error` is recorded, but `path_argument` is NOT, since `recordFilePaths` is off | ||
| data: { | ||
| fs_error: expect.stringMatching('ENOENT: no such file or directory,'), | ||
| [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', | ||
| [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', | ||
| }, | ||
| }), | ||
| ]), | ||
| }, | ||
| }) | ||
| .start(); | ||
|
|
||
| const result = await runner.makeRequest('get', '/readFile-error'); | ||
| expect(result).toEqual('done'); | ||
| await runner.completed(); | ||
| }); | ||
|
|
||
| test('does not record file paths on successful operations when only `recordErrorMessagesAsSpanAttributes` is enabled', async () => { | ||
| const runner = createRunner(__dirname, 'server-record-errors-only.ts') | ||
| .expect({ | ||
| transaction: { | ||
| transaction: 'GET /readFile', | ||
| spans: expect.arrayContaining([ | ||
| expect.objectContaining({ | ||
| description: 'fs.readFile', | ||
| op: 'file', | ||
| status: 'ok', | ||
| // Neither `path_argument` nor `fs_error` are recorded | ||
| data: { | ||
| [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', | ||
| [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', | ||
| }, | ||
| }), | ||
| ]), | ||
| }, | ||
| }) | ||
| .start(); | ||
|
|
||
| const result = await runner.makeRequest('get', '/readFile'); | ||
| expect(result).toEqual('done'); | ||
| await runner.completed(); | ||
| }); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Option gating tests omit absence checksMedium Severity The new Triggered by project rule: PR Review Guidelines for Cursor Bot Reviewed by Cursor Bugbot for commit 5754444. Configure here. |
||


Uh oh!
There was an error while loading. Please reload this page.