diff --git a/packages/serverless/src/awsservices.ts b/packages/serverless/src/awsservices.ts index 41b73f58464e..8992b7a7adb0 100644 --- a/packages/serverless/src/awsservices.ts +++ b/packages/serverless/src/awsservices.ts @@ -1,4 +1,4 @@ -import { getCurrentScope } from '@sentry/node'; +import { startInactiveSpan } from '@sentry/node'; import type { Integration, Span } from '@sentry/types'; import { fill } from '@sentry/utils'; // 'aws-sdk/global' import is expected to be type-only so it's erased in the final .js file. @@ -57,19 +57,13 @@ function wrapMakeRequest( ): MakeRequestFunction { return function (this: TService, operation: string, params?: GenericParams, callback?: MakeRequestCallback) { let span: Span | undefined; - const scope = getCurrentScope(); - // eslint-disable-next-line deprecation/deprecation - const transaction = scope.getTransaction(); const req = orig.call(this, operation, params); req.on('afterBuild', () => { - if (transaction) { - // eslint-disable-next-line deprecation/deprecation - span = transaction.startChild({ - description: describe(this, operation, params), - op: 'http.client', - origin: 'auto.http.serverless', - }); - } + span = startInactiveSpan({ + name: describe(this, operation, params), + op: 'http.client', + origin: 'auto.http.serverless', + }); }); req.on('complete', () => { if (span) { diff --git a/packages/serverless/src/google-cloud-grpc.ts b/packages/serverless/src/google-cloud-grpc.ts index 74a88f622333..458af78872f7 100644 --- a/packages/serverless/src/google-cloud-grpc.ts +++ b/packages/serverless/src/google-cloud-grpc.ts @@ -1,6 +1,6 @@ import type { EventEmitter } from 'events'; -import { getCurrentScope } from '@sentry/node'; -import type { Integration, Span } from '@sentry/types'; +import { startInactiveSpan } from '@sentry/node'; +import type { Integration } from '@sentry/types'; import { fill } from '@sentry/utils'; interface GrpcFunction extends CallableFunction { @@ -107,18 +107,11 @@ function fillGrpcFunction(stub: Stub, serviceIdentifier: string, methodName: str if (typeof ret?.on !== 'function') { return ret; } - let span: Span | undefined; - const scope = getCurrentScope(); - // eslint-disable-next-line deprecation/deprecation - const transaction = scope.getTransaction(); - if (transaction) { - // eslint-disable-next-line deprecation/deprecation - span = transaction.startChild({ - description: `${callType} ${methodName}`, - op: `grpc.${serviceIdentifier}`, - origin: 'auto.grpc.serverless', - }); - } + const span = startInactiveSpan({ + name: `${callType} ${methodName}`, + op: `grpc.${serviceIdentifier}`, + origin: 'auto.grpc.serverless', + }); ret.on('status', () => { if (span) { span.end(); diff --git a/packages/serverless/src/google-cloud-http.ts b/packages/serverless/src/google-cloud-http.ts index 87687a52f82e..369fa6ad230d 100644 --- a/packages/serverless/src/google-cloud-http.ts +++ b/packages/serverless/src/google-cloud-http.ts @@ -1,8 +1,8 @@ // '@google-cloud/common' import is expected to be type-only so it's erased in the final .js file. // When TypeScript compiler is upgraded, use `import type` syntax to explicitly assert that we don't want to load a module here. import type * as common from '@google-cloud/common'; -import { getCurrentScope } from '@sentry/node'; -import type { Integration, Span } from '@sentry/types'; +import { startInactiveSpan } from '@sentry/node'; +import type { Integration } from '@sentry/types'; import { fill } from '@sentry/utils'; type RequestOptions = common.DecorateRequestOptions; @@ -51,19 +51,12 @@ export class GoogleCloudHttp implements Integration { /** Returns a wrapped function that makes a request with tracing enabled */ function wrapRequestFunction(orig: RequestFunction): RequestFunction { return function (this: common.Service, reqOpts: RequestOptions, callback: ResponseCallback): void { - let span: Span | undefined; - const scope = getCurrentScope(); - // eslint-disable-next-line deprecation/deprecation - const transaction = scope.getTransaction(); - if (transaction) { - const httpMethod = reqOpts.method || 'GET'; - // eslint-disable-next-line deprecation/deprecation - span = transaction.startChild({ - description: `${httpMethod} ${reqOpts.uri}`, - op: `http.client.${identifyService(this.apiEndpoint)}`, - origin: 'auto.http.serverless', - }); - } + const httpMethod = reqOpts.method || 'GET'; + const span = startInactiveSpan({ + name: `${httpMethod} ${reqOpts.uri}`, + op: `http.client.${identifyService(this.apiEndpoint)}`, + origin: 'auto.http.serverless', + }); orig.call(this, reqOpts, (...args: Parameters) => { if (span) { span.end(); diff --git a/packages/serverless/test/__mocks__/@sentry/node.ts b/packages/serverless/test/__mocks__/@sentry/node.ts index fb929737f8d4..b3ff9edeaa9f 100644 --- a/packages/serverless/test/__mocks__/@sentry/node.ts +++ b/packages/serverless/test/__mocks__/@sentry/node.ts @@ -14,7 +14,6 @@ export const fakeScope = { setTag: jest.fn(), setContext: jest.fn(), setSpan: jest.fn(), - getTransaction: jest.fn(() => fakeTransaction), setSDKProcessingMetadata: jest.fn(), setPropagationContext: jest.fn(), }; @@ -22,11 +21,6 @@ export const fakeSpan = { end: jest.fn(), setHttpStatus: jest.fn(), }; -export const fakeTransaction = { - end: jest.fn(), - setHttpStatus: jest.fn(), - startChild: jest.fn(() => fakeSpan), -}; export const init = jest.fn(); export const addGlobalEventProcessor = jest.fn(); export const getCurrentScope = jest.fn(() => fakeScope); @@ -36,11 +30,9 @@ export const withScope = jest.fn(cb => cb(fakeScope)); export const flush = jest.fn(() => Promise.resolve()); export const getClient = jest.fn(() => ({})); export const startSpanManual = jest.fn((ctx, callback: (span: any) => any) => callback(fakeSpan)); +export const startInactiveSpan = jest.fn(() => fakeSpan); export const resetMocks = (): void => { - fakeTransaction.setHttpStatus.mockClear(); - fakeTransaction.end.mockClear(); - fakeTransaction.startChild.mockClear(); fakeSpan.end.mockClear(); fakeSpan.setHttpStatus.mockClear(); @@ -48,7 +40,6 @@ export const resetMocks = (): void => { fakeScope.setTag.mockClear(); fakeScope.setContext.mockClear(); fakeScope.setSpan.mockClear(); - fakeScope.getTransaction.mockClear(); init.mockClear(); addGlobalEventProcessor.mockClear(); diff --git a/packages/serverless/test/awslambda.test.ts b/packages/serverless/test/awslambda.test.ts index 0da204b31fa4..0d923074067f 100644 --- a/packages/serverless/test/awslambda.test.ts +++ b/packages/serverless/test/awslambda.test.ts @@ -8,13 +8,6 @@ import * as Sentry from '../src'; const { wrapHandler } = Sentry.AWSLambda; -/** - * Why @ts-expect-error some Sentry.X calls - * - * A hack-ish way to contain everything related to mocks in the same __mocks__ file. - * Thanks to this, we don't have to do more magic than necessary. Just add and export desired method and assert on it. - */ - // Default `timeoutWarningLimit` is 500ms so leaving some space for it to trigger when necessary const DEFAULT_EXECUTION_TIME = 100; let fakeEvent: { [key: string]: unknown }; diff --git a/packages/serverless/test/awsservices.test.ts b/packages/serverless/test/awsservices.test.ts index e4abda7c9364..16464e315fa6 100644 --- a/packages/serverless/test/awsservices.test.ts +++ b/packages/serverless/test/awsservices.test.ts @@ -4,13 +4,6 @@ import * as nock from 'nock'; import { AWSServices } from '../src/awsservices'; -/** - * Why @ts-expect-error some Sentry.X calls - * - * A hack-ish way to contain everything related to mocks in the same __mocks__ file. - * Thanks to this, we don't have to do more magic than necessary. Just add and export desired method and assert on it. - */ - describe('AWSServices', () => { beforeAll(() => { new AWSServices().setupOnce(); @@ -30,11 +23,10 @@ describe('AWSServices', () => { nock('https://foo.s3.amazonaws.com').get('/bar').reply(200, 'contents'); const data = await s3.getObject({ Bucket: 'foo', Key: 'bar' }).promise(); expect(data.Body?.toString('utf-8')).toEqual('contents'); - // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.startChild).toBeCalledWith({ + expect(SentryNode.startInactiveSpan).toBeCalledWith({ op: 'http.client', origin: 'auto.http.serverless', - description: 'aws.s3.getObject foo', + name: 'aws.s3.getObject foo', }); // @ts-expect-error see "Why @ts-expect-error" note expect(SentryNode.fakeSpan.end).toBeCalled(); @@ -48,11 +40,10 @@ describe('AWSServices', () => { expect(data.Body?.toString('utf-8')).toEqual('contents'); done(); }); - // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.startChild).toBeCalledWith({ + expect(SentryNode.startInactiveSpan).toBeCalledWith({ op: 'http.client', origin: 'auto.http.serverless', - description: 'aws.s3.getObject foo', + name: 'aws.s3.getObject foo', }); }); }); @@ -64,11 +55,10 @@ describe('AWSServices', () => { nock('https://lambda.eu-north-1.amazonaws.com').post('/2015-03-31/functions/foo/invocations').reply(201, 'reply'); const data = await lambda.invoke({ FunctionName: 'foo' }).promise(); expect(data.Payload?.toString('utf-8')).toEqual('reply'); - // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.startChild).toBeCalledWith({ + expect(SentryNode.startInactiveSpan).toBeCalledWith({ op: 'http.client', origin: 'auto.http.serverless', - description: 'aws.lambda.invoke foo', + name: 'aws.lambda.invoke foo', }); }); }); diff --git a/packages/serverless/test/gcpfunction.test.ts b/packages/serverless/test/gcpfunction.test.ts index f4486415988b..29cfe0541a0c 100644 --- a/packages/serverless/test/gcpfunction.test.ts +++ b/packages/serverless/test/gcpfunction.test.ts @@ -14,12 +14,6 @@ import type { Request, Response, } from '../src/gcpfunction/general'; -/** - * Why @ts-expect-error some Sentry.X calls - * - * A hack-ish way to contain everything related to mocks in the same __mocks__ file. - * Thanks to this, we don't have to do more magic than necessary. Just add and export desired method and assert on it. - */ describe('GCPFunction', () => { afterEach(() => { diff --git a/packages/serverless/test/google-cloud-grpc.test.ts b/packages/serverless/test/google-cloud-grpc.test.ts index a9fd8f726e08..39ebb4a54ecd 100644 --- a/packages/serverless/test/google-cloud-grpc.test.ts +++ b/packages/serverless/test/google-cloud-grpc.test.ts @@ -11,13 +11,6 @@ import * as nock from 'nock'; import { GoogleCloudGrpc } from '../src/google-cloud-grpc'; -/** - * Why @ts-expect-error some Sentry.X calls - * - * A hack-ish way to contain everything related to mocks in the same __mocks__ file. - * Thanks to this, we don't have to do more magic than necessary. Just add and export desired method and assert on it. - */ - const spyConnect = jest.spyOn(http2, 'connect'); /** Fake HTTP2 stream */ @@ -126,11 +119,10 @@ describe('GoogleCloudGrpc tracing', () => { mockHttp2Session().mockUnaryRequest(Buffer.from('00000000120a1031363337303834313536363233383630', 'hex')); const resp = await pubsub.topic('nicetopic').publish(Buffer.from('data')); expect(resp).toEqual('1637084156623860'); - // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.startChild).toBeCalledWith({ + expect(SentryNode.startInactiveSpan).toBeCalledWith({ op: 'grpc.pubsub', origin: 'auto.grpc.serverless', - description: 'unary call publish', + name: 'unary call publish', }); await pubsub.close(); }); diff --git a/packages/serverless/test/google-cloud-http.test.ts b/packages/serverless/test/google-cloud-http.test.ts index b285a9a862c8..0ef1466647a5 100644 --- a/packages/serverless/test/google-cloud-http.test.ts +++ b/packages/serverless/test/google-cloud-http.test.ts @@ -6,13 +6,6 @@ import * as nock from 'nock'; import { GoogleCloudHttp } from '../src/google-cloud-http'; -/** - * Why @ts-expect-error some Sentry.X calls - * - * A hack-ish way to contain everything related to mocks in the same __mocks__ file. - * Thanks to this, we don't have to do more magic than necessary. Just add and export desired method and assert on it. - */ - describe('GoogleCloudHttp tracing', () => { beforeAll(() => { new GoogleCloudHttp().setupOnce(); @@ -57,17 +50,15 @@ describe('GoogleCloudHttp tracing', () => { ); const resp = await bigquery.query('SELECT true AS foo'); expect(resp).toEqual([[{ foo: true }]]); - // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.startChild).toBeCalledWith({ + expect(SentryNode.startInactiveSpan).toBeCalledWith({ op: 'http.client.bigquery', origin: 'auto.http.serverless', - description: 'POST /jobs', + name: 'POST /jobs', }); - // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.startChild).toBeCalledWith({ + expect(SentryNode.startInactiveSpan).toBeCalledWith({ op: 'http.client.bigquery', origin: 'auto.http.serverless', - description: expect.stringMatching(/^GET \/queries\/.+/), + name: expect.stringMatching(/^GET \/queries\/.+/), }); }); });