From 9f4aaa4b1cc6f6d7531bceb79ba2668e485d3406 Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Wed, 23 Sep 2026 14:03:53 +0200 Subject: [PATCH] feat(server-utils): Support tedious v20 Fixes #24643 Co-Authored-By: Claude Opus 5.5 --- .../suites/tracing/tedious/test.ts | 41 +++++++++++++++++++ .../src/orchestrion/config/tedious.ts | 2 +- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/dev-packages/node-integration-tests/suites/tracing/tedious/test.ts b/dev-packages/node-integration-tests/suites/tracing/tedious/test.ts index 9e9d6b7e3291..eb5c81a0a49d 100644 --- a/dev-packages/node-integration-tests/suites/tracing/tedious/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/tedious/test.ts @@ -1,4 +1,5 @@ import { afterAll, expect } from 'vitest'; +import { conditionalTest } from '../../../utils'; import { cleanupChildProcesses, createEsmAndCjsTests, describeWithDockerCompose } from '../../../utils/runner'; describeWithDockerCompose('tedious auto instrumentation', { workingDirectory: [__dirname] }, () => { @@ -92,6 +93,46 @@ describeWithDockerCompose('tedious auto instrumentation', { workingDirectory: [_ }); }); + // tedious 20 requires Node >= 22. + conditionalTest({ min: 22 })('tedious v20', () => { + createEsmAndCjsTests( + __dirname, + 'scenario.mjs', + 'instrument-span-streaming.mjs', + (createTestRunner, test) => { + test('should auto-instrument `tedious` package', async () => { + await createTestRunner() + .expect({ + span: container => { + const dbSpans = container.items.filter(item => item.attributes['sentry.origin']?.value === ORIGIN); + + expect(dbSpans.map(span => span.name)).toEqual( + expect.arrayContaining([ + 'SELECT', + 'callProcedure [dbo].[test_proced]', + 'INSERT [dbo].[test_prepared]', + 'execBulkLoad test_bulk', + 'SELECT [dbo].[test_bulk]', + ]), + ); + expect(dbSpans.find(span => span.name === 'select')?.status).toBe('error'); + expect(dbSpans[0]?.attributes).toMatchObject({ + 'db.system.name': { value: 'mssql' }, + 'db.namespace': { value: 'master' }, + 'db.user': { value: 'sa' }, + 'server.address': { value: '127.0.0.1' }, + 'server.port': { value: 1433 }, + }); + }, + }) + .start() + .completed(); + }); + }, + { additionalDependencies: { tedious: '^20' } }, + ); + }); + createEsmAndCjsTests(__dirname, 'scenario.mjs', 'instrument-span-streaming.mjs', (createTestRunner, test) => { test('should name spans after the query summary with span streaming', async () => { await createTestRunner() diff --git a/packages/server-utils/src/orchestrion/config/tedious.ts b/packages/server-utils/src/orchestrion/config/tedious.ts index 61af25ca2570..943d27cb476b 100644 --- a/packages/server-utils/src/orchestrion/config/tedious.ts +++ b/packages/server-utils/src/orchestrion/config/tedious.ts @@ -8,7 +8,7 @@ const MODULE_NAME = 'tedious'; // OTel `supportedVersions`). Orchestrion never matches a file that doesn't exist, so a single entry is // safe even for versions that shipped extra layouts. const FILE_PATH = 'lib/connection.js'; -const VERSION_RANGE = '>=1.11.0 <20'; +const VERSION_RANGE = '>=1.11.0 <21'; // `Connection` methods that dispatch a request (each traced as one db span) plus `connect`, which the // subscriber wraps for bookkeeping only (tracking the connection's active database, read into `db.name`).