diff --git a/packages/angular/src/tracing.ts b/packages/angular/src/tracing.ts index 25ddc2fd8dcf..3138f1be1c53 100644 --- a/packages/angular/src/tracing.ts +++ b/packages/angular/src/tracing.ts @@ -82,7 +82,7 @@ export class TraceService implements OnDestroy { if (activeTransaction) { if (this._routingSpan) { - this._routingSpan.finish(); + this._routingSpan.end(); } this._routingSpan = activeTransaction.startChild({ description: `${navigationEvent.url}`, @@ -131,7 +131,7 @@ export class TraceService implements OnDestroy { if (this._routingSpan) { runOutsideAngular(() => { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - this._routingSpan!.finish(); + this._routingSpan!.end(); }); this._routingSpan = null; } @@ -196,7 +196,7 @@ export class TraceDirective implements OnInit, AfterViewInit { */ public ngAfterViewInit(): void { if (this._tracingSpan) { - this._tracingSpan.finish(); + this._tracingSpan.end(); } } } @@ -239,7 +239,7 @@ export function TraceClassDecorator(): ClassDecorator { // eslint-disable-next-line @typescript-eslint/no-explicit-any target.prototype.ngAfterViewInit = function (...args: any[]): ReturnType { if (tracingSpan) { - tracingSpan.finish(); + tracingSpan.end(); } if (originalAfterViewInit) { return originalAfterViewInit.apply(this, args); diff --git a/packages/angular/test/tracing.test.ts b/packages/angular/test/tracing.test.ts index 635c8847b9bf..a407539026c5 100644 --- a/packages/angular/test/tracing.test.ts +++ b/packages/angular/test/tracing.test.ts @@ -154,7 +154,7 @@ describe('Angular Tracing', () => { const finishMock = jest.fn(); transaction.startChild = jest.fn(() => ({ - finish: finishMock, + end: finishMock, })); await env.navigateInAngular('/'); @@ -173,7 +173,7 @@ describe('Angular Tracing', () => { const finishMock = jest.fn(); transaction.startChild = jest.fn(() => ({ - finish: finishMock, + end: finishMock, })); await env.navigateInAngular('/'); @@ -199,7 +199,7 @@ describe('Angular Tracing', () => { const finishMock = jest.fn(); transaction.startChild = jest.fn(() => ({ - finish: finishMock, + end: finishMock, })); await env.navigateInAngular('/somewhere'); @@ -233,7 +233,7 @@ describe('Angular Tracing', () => { const finishMock = jest.fn(); transaction.startChild = jest.fn(() => ({ - finish: finishMock, + end: finishMock, })); await env.navigateInAngular('/cancel'); @@ -376,7 +376,7 @@ describe('Angular Tracing', () => { }); transaction.startChild = jest.fn(() => ({ - finish: finishMock, + end: finishMock, })); directive.componentName = 'test-component'; @@ -403,7 +403,7 @@ describe('Angular Tracing', () => { }); transaction.startChild = jest.fn(() => ({ - finish: finishMock, + end: finishMock, })); directive.ngOnInit(); @@ -437,7 +437,7 @@ describe('Angular Tracing', () => { it('Instruments `ngOnInit` and `ngAfterViewInit` methods of the decorated class', async () => { const finishMock = jest.fn(); const startChildMock = jest.fn(() => ({ - finish: finishMock, + end: finishMock, })); const customStartTransaction = jest.fn((ctx: any) => { diff --git a/packages/browser-integration-tests/suites/public-api/startTransaction/basic_usage/subject.js b/packages/browser-integration-tests/suites/public-api/startTransaction/basic_usage/subject.js index e46009e46b35..0d79bddf53a5 100644 --- a/packages/browser-integration-tests/suites/public-api/startTransaction/basic_usage/subject.js +++ b/packages/browser-integration-tests/suites/public-api/startTransaction/basic_usage/subject.js @@ -11,7 +11,7 @@ async function run() { await new Promise(resolve => setTimeout(resolve, 1)); // span_1 finishes - span_1.finish(); + span_1.end(); // span_2 doesn't finish const span_2 = transaction.startChild({ op: 'span_2' }); @@ -24,12 +24,12 @@ async function run() { const span_4 = span_3.startChild({ op: 'span_4', data: { qux: 'quux' } }); // span_5 is another child of span_3 but finishes. - const span_5 = span_3.startChild({ op: 'span_5' }).finish(); + const span_5 = span_3.startChild({ op: 'span_5' }).end(); // span_3 also finishes - span_3.finish(); + span_3.end(); - transaction.finish(); + transaction.end(); } run(); diff --git a/packages/browser-integration-tests/suites/public-api/startTransaction/circular_data/subject.js b/packages/browser-integration-tests/suites/public-api/startTransaction/circular_data/subject.js index 50f8cef000be..d2ae465addf7 100644 --- a/packages/browser-integration-tests/suites/public-api/startTransaction/circular_data/subject.js +++ b/packages/browser-integration-tests/suites/public-api/startTransaction/circular_data/subject.js @@ -7,5 +7,5 @@ const circularObject = chicken; const transaction = Sentry.startTransaction({ name: 'circular_object_test_transaction', data: circularObject }); const span = transaction.startChild({ op: 'circular_object_test_span', data: circularObject }); -span.finish(); -transaction.finish(); +span.end(); +transaction.end(); diff --git a/packages/browser-integration-tests/suites/public-api/startTransaction/setMeasurement/subject.js b/packages/browser-integration-tests/suites/public-api/startTransaction/setMeasurement/subject.js index 036e86201b18..5b14dd7b680b 100644 --- a/packages/browser-integration-tests/suites/public-api/startTransaction/setMeasurement/subject.js +++ b/packages/browser-integration-tests/suites/public-api/startTransaction/setMeasurement/subject.js @@ -5,4 +5,4 @@ transaction.setMeasurement('metric.bar', 1337, 'nanoseconds'); transaction.setMeasurement('metric.baz', 99, 's'); transaction.setMeasurement('metric.baz', 1); -transaction.finish(); +transaction.end(); diff --git a/packages/browser/src/profiling/hubextensions.ts b/packages/browser/src/profiling/hubextensions.ts index f042ae016609..462929fff04b 100644 --- a/packages/browser/src/profiling/hubextensions.ts +++ b/packages/browser/src/profiling/hubextensions.ts @@ -143,34 +143,34 @@ export function startProfileForTransaction(transaction: Transaction): Transactio onProfileHandler(); }, MAX_PROFILE_DURATION_MS); - // We need to reference the original finish call to avoid creating an infinite loop - const originalFinish = transaction.finish.bind(transaction); + // We need to reference the original end call to avoid creating an infinite loop + const originalEnd = transaction.end.bind(transaction); /** * Wraps startTransaction and stopTransaction with profiling related logic. * startProfiling is called after the call to startTransaction in order to avoid our own code from * being profiled. Because of that same reason, stopProfiling is called before the call to stopTransaction. */ - function profilingWrappedTransactionFinish(): Transaction { + function profilingWrappedTransactionEnd(): Transaction { if (!transaction) { - return originalFinish(); + return originalEnd(); } // onProfileHandler should always return the same profile even if this is called multiple times. // Always call onProfileHandler to ensure stopProfiling is called and the timeout is cleared. void onProfileHandler().then( () => { transaction.setContext('profile', { profile_id: profileId, start_timestamp: startTimestamp }); - originalFinish(); + originalEnd(); }, () => { // If onProfileHandler fails, we still want to call the original finish method. - originalFinish(); + originalEnd(); }, ); return transaction; } - transaction.finish = profilingWrappedTransactionFinish; + transaction.end = profilingWrappedTransactionEnd; return transaction; } diff --git a/packages/browser/test/unit/profiling/integration.test.ts b/packages/browser/test/unit/profiling/integration.test.ts index 515398638048..ae95927ac2cd 100644 --- a/packages/browser/test/unit/profiling/integration.test.ts +++ b/packages/browser/test/unit/profiling/integration.test.ts @@ -52,7 +52,7 @@ describe('BrowserProfilingIntegration', () => { const currentTransaction = Sentry.getCurrentHub().getScope().getTransaction(); expect(currentTransaction?.op).toBe('pageload'); - currentTransaction?.finish(); + currentTransaction?.end(); await client?.flush(1000); expect(send).toHaveBeenCalledTimes(1); diff --git a/packages/core/src/exports.ts b/packages/core/src/exports.ts index 95c1e4b63de3..d7757e7d5d37 100644 --- a/packages/core/src/exports.ts +++ b/packages/core/src/exports.ts @@ -179,7 +179,7 @@ export function withScope(callback: (scope: Scope) => T): T { * * Every child span must be finished before the transaction is finished, otherwise the unfinished spans are discarded. * - * The transaction must be finished with a call to its `.finish()` method, at which point the transaction with all its + * The transaction must be finished with a call to its `.end()` method, at which point the transaction with all its * finished child spans will be sent to Sentry. * * NOTE: This function should only be used for *manual* instrumentation. Auto-instrumentation should call diff --git a/packages/core/src/tracing/idletransaction.ts b/packages/core/src/tracing/idletransaction.ts index 75630de373f1..458bd9281627 100644 --- a/packages/core/src/tracing/idletransaction.ts +++ b/packages/core/src/tracing/idletransaction.ts @@ -7,6 +7,7 @@ import type { Hub } from '../hub'; import type { Span } from './span'; import { SpanRecorder } from './span'; import { Transaction } from './transaction'; +import { ensureTimestampInSeconds } from './utils'; export const TRACING_DEFAULTS = { idleTimeout: 1000, @@ -45,10 +46,12 @@ export class IdleTransactionSpanRecorder extends SpanRecorder { // We should make sure we do not push and pop activities for // the transaction that this span recorder belongs to. if (span.spanId !== this.transactionSpanId) { - // We patch span.finish() to pop an activity after setting an endTimestamp. - span.finish = (endTimestamp?: number) => { - span.endTimestamp = typeof endTimestamp === 'number' ? endTimestamp : timestampInSeconds(); + // We patch span.end() to pop an activity after setting an endTimestamp. + // eslint-disable-next-line @typescript-eslint/unbound-method + const originalEnd = span.end; + span.end = (...rest: unknown[]) => { this._popActivity(span.spanId); + return originalEnd.apply(span, rest); }; // We should only push new activities if the span does not have an end timestamp. @@ -129,13 +132,15 @@ export class IdleTransaction extends Transaction { if (!this._finished) { this.setStatus('deadline_exceeded'); this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[3]; - this.finish(); + this.end(); } }, this._finalTimeout); } /** {@inheritDoc} */ - public finish(endTimestamp: number = timestampInSeconds()): string | undefined { + public end(endTimestamp: number = timestampInSeconds()): string | undefined { + const endTimestampInS = ensureTimestampInSeconds(endTimestamp); + this._finished = true; this.activities = {}; @@ -145,7 +150,7 @@ export class IdleTransaction extends Transaction { if (this.spanRecorder) { DEBUG_BUILD && - logger.log('[Tracing] finishing IdleTransaction', new Date(endTimestamp * 1000).toISOString(), this.op); + logger.log('[Tracing] finishing IdleTransaction', new Date(endTimestampInS * 1000).toISOString(), this.op); for (const callback of this._beforeFinishCallbacks) { callback(this, endTimestamp); @@ -159,13 +164,13 @@ export class IdleTransaction extends Transaction { // We cancel all pending spans with status "cancelled" to indicate the idle transaction was finished early if (!span.endTimestamp) { - span.endTimestamp = endTimestamp; + span.endTimestamp = endTimestampInS; span.setStatus('cancelled'); DEBUG_BUILD && logger.log('[Tracing] cancelling span since transaction ended early', JSON.stringify(span, undefined, 2)); } - const spanStartedBeforeTransactionFinish = span.startTimestamp < endTimestamp; + const spanStartedBeforeTransactionFinish = span.startTimestamp < endTimestampInS; // Add a delta with idle timeout so that we prevent false positives const timeoutWithMarginOfError = (this._finalTimeout + this._idleTimeout) / 1000; @@ -196,7 +201,7 @@ export class IdleTransaction extends Transaction { } } - return super.finish(endTimestamp); + return super.end(endTimestamp); } /** @@ -244,7 +249,7 @@ export class IdleTransaction extends Transaction { * with the last child span. */ public cancelIdleTimeout( - endTimestamp?: Parameters[0], + endTimestamp?: Parameters[0], { restartOnChildSpanChange, }: { @@ -260,7 +265,7 @@ export class IdleTransaction extends Transaction { if (Object.keys(this.activities).length === 0 && this._idleTimeoutCanceledPermanently) { this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[5]; - this.finish(endTimestamp); + this.end(endTimestamp); } } } @@ -281,12 +286,12 @@ export class IdleTransaction extends Transaction { /** * Restarts idle timeout, if there is no running idle timeout it will start one. */ - private _restartIdleTimeout(endTimestamp?: Parameters[0]): void { + private _restartIdleTimeout(endTimestamp?: Parameters[0]): void { this.cancelIdleTimeout(); this._idleTimeoutID = setTimeout(() => { if (!this._finished && Object.keys(this.activities).length === 0) { this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[1]; - this.finish(endTimestamp); + this.end(endTimestamp); } }, this._idleTimeout); } @@ -318,7 +323,7 @@ export class IdleTransaction extends Transaction { const endTimestamp = timestampInSeconds(); if (this._idleTimeoutCanceledPermanently) { this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[5]; - this.finish(endTimestamp); + this.end(endTimestamp); } else { // We need to add the timeout here to have the real endtimestamp of the transaction // Remember timestampInSeconds is in seconds, timeout is in ms @@ -351,7 +356,7 @@ export class IdleTransaction extends Transaction { DEBUG_BUILD && logger.log('[Tracing] Transaction finished because of no change for 3 heart beats'); this.setStatus('deadline_exceeded'); this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[0]; - this.finish(); + this.end(); } else { this._pingHeartbeat(); } diff --git a/packages/core/src/tracing/span.ts b/packages/core/src/tracing/span.ts index 4b341a71e2c2..80704d44c9a7 100644 --- a/packages/core/src/tracing/span.ts +++ b/packages/core/src/tracing/span.ts @@ -11,6 +11,7 @@ import type { import { dropUndefinedKeys, generateSentryTraceHeader, logger, timestampInSeconds, uuid4 } from '@sentry/utils'; import { DEBUG_BUILD } from '../debug-build'; +import { ensureTimestampInSeconds } from './utils'; /** * Keeps track of finished spans for a given transaction @@ -259,8 +260,15 @@ export class Span implements SpanInterface { /** * @inheritDoc + * + * @deprecated Use `.end()` instead. */ public finish(endTimestamp?: number): void { + return this.end(endTimestamp); + } + + /** @inheritdoc */ + public end(endTimestamp?: number): void { if ( DEBUG_BUILD && // Don't call this for transactions @@ -273,7 +281,8 @@ export class Span implements SpanInterface { } } - this.endTimestamp = typeof endTimestamp === 'number' ? endTimestamp : timestampInSeconds(); + this.endTimestamp = + typeof endTimestamp === 'number' ? ensureTimestampInSeconds(endTimestamp) : timestampInSeconds(); } /** diff --git a/packages/core/src/tracing/trace.ts b/packages/core/src/tracing/trace.ts index cc73fe009e3d..52c915c30189 100644 --- a/packages/core/src/tracing/trace.ts +++ b/packages/core/src/tracing/trace.ts @@ -39,7 +39,7 @@ export function trace( scope.setSpan(activeSpan); function finishAndSetSpan(): void { - activeSpan && activeSpan.finish(); + activeSpan && activeSpan.end(); scope.setSpan(parentSpan); } @@ -97,7 +97,7 @@ export function startSpan(context: TransactionContext, callback: (span: Span scope.setSpan(activeSpan); function finishAndSetSpan(): void { - activeSpan && activeSpan.finish(); + activeSpan && activeSpan.end(); scope.setSpan(parentSpan); } @@ -157,7 +157,7 @@ export function startSpanManual( scope.setSpan(activeSpan); function finishAndSetSpan(): void { - activeSpan && activeSpan.finish(); + activeSpan && activeSpan.end(); scope.setSpan(parentSpan); } diff --git a/packages/core/src/tracing/transaction.ts b/packages/core/src/tracing/transaction.ts index be2e7324769a..59591971d24e 100644 --- a/packages/core/src/tracing/transaction.ts +++ b/packages/core/src/tracing/transaction.ts @@ -9,13 +9,14 @@ import type { TransactionEvent, TransactionMetadata, } from '@sentry/types'; -import { dropUndefinedKeys, logger } from '@sentry/utils'; +import { dropUndefinedKeys, logger, timestampInSeconds } from '@sentry/utils'; import { DEBUG_BUILD } from '../debug-build'; import type { Hub } from '../hub'; import { getCurrentHub } from '../hub'; import { getDynamicSamplingContextFromClient } from './dynamicSamplingContext'; import { Span as SpanClass, SpanRecorder } from './span'; +import { ensureTimestampInSeconds } from './utils'; /** JSDoc */ export class Transaction extends SpanClass implements TransactionInterface { @@ -134,8 +135,10 @@ export class Transaction extends SpanClass implements TransactionInterface { /** * @inheritDoc */ - public finish(endTimestamp?: number): string | undefined { - const transaction = this._finishTransaction(endTimestamp); + public end(endTimestamp?: number): string | undefined { + const timestampInS = + typeof endTimestamp === 'number' ? ensureTimestampInSeconds(endTimestamp) : timestampInSeconds(); + const transaction = this._finishTransaction(timestampInS); if (!transaction) { return undefined; } @@ -232,7 +235,7 @@ export class Transaction extends SpanClass implements TransactionInterface { } // just sets the end timestamp - super.finish(endTimestamp); + super.end(endTimestamp); const client = this._hub.getClient(); if (client && client.emit) { diff --git a/packages/core/src/tracing/utils.ts b/packages/core/src/tracing/utils.ts index f1b4c0f1ae06..4c1d49780554 100644 --- a/packages/core/src/tracing/utils.ts +++ b/packages/core/src/tracing/utils.ts @@ -27,3 +27,11 @@ export { stripUrlQueryAndFragment } from '@sentry/utils'; * @deprecated Import this function from `@sentry/utils` instead */ export const extractTraceparentData = _extractTraceparentData; + +/** + * Converts a timestamp to second, if it was in milliseconds, or keeps it as second. + */ +export function ensureTimestampInSeconds(timestamp: number): number { + const isMs = timestamp > 9999999999; + return isMs ? timestamp / 1000 : timestamp; +} diff --git a/packages/core/test/lib/tracing/errors.test.ts b/packages/core/test/lib/tracing/errors.test.ts index 20db043865a9..60b5db5c0c1d 100644 --- a/packages/core/test/lib/tracing/errors.test.ts +++ b/packages/core/test/lib/tracing/errors.test.ts @@ -61,7 +61,7 @@ describe('registerErrorHandlers()', () => { mockUnhandledRejectionCallback({}); expect(transaction.status).toBe(undefined); - transaction.finish(); + transaction.end(); }); it('sets status for transaction on scope on error', () => { @@ -72,7 +72,7 @@ describe('registerErrorHandlers()', () => { mockErrorCallback({} as HandlerDataError); expect(transaction.status).toBe('internal_error'); - transaction.finish(); + transaction.end(); }); it('sets status for transaction on scope on unhandledrejection', () => { @@ -82,6 +82,6 @@ describe('registerErrorHandlers()', () => { mockUnhandledRejectionCallback({}); expect(transaction.status).toBe('internal_error'); - transaction.finish(); + transaction.end(); }); }); diff --git a/packages/e2e-tests/test-applications/create-next-app/pages/api/success.ts b/packages/e2e-tests/test-applications/create-next-app/pages/api/success.ts index 7585c88f0ab1..8a5a53f2e4dc 100644 --- a/packages/e2e-tests/test-applications/create-next-app/pages/api/success.ts +++ b/packages/e2e-tests/test-applications/create-next-app/pages/api/success.ts @@ -8,8 +8,8 @@ export default function handler(req: NextApiRequest, res: NextApiResponse) { const span = transaction.startChild(); - span.finish(); - transaction.finish(); + span.end(); + transaction.end(); Sentry.flush().then(() => { res.status(200).json({ diff --git a/packages/e2e-tests/test-applications/nextjs-app-dir/components/transaction-context.tsx b/packages/e2e-tests/test-applications/nextjs-app-dir/components/transaction-context.tsx index 4102a1a422a8..ef1915b98af7 100644 --- a/packages/e2e-tests/test-applications/nextjs-app-dir/components/transaction-context.tsx +++ b/packages/e2e-tests/test-applications/nextjs-app-dir/components/transaction-context.tsx @@ -21,7 +21,7 @@ export function TransactionContextProvider({ children }: PropsWithChildren) { ? { transactionActive: true, stop: () => { - transaction.finish(); + transaction.end(); setTransaction(undefined); }, } diff --git a/packages/e2e-tests/test-applications/node-express-app/src/app.ts b/packages/e2e-tests/test-applications/node-express-app/src/app.ts index 330a425cb494..269f8df45bbe 100644 --- a/packages/e2e-tests/test-applications/node-express-app/src/app.ts +++ b/packages/e2e-tests/test-applications/node-express-app/src/app.ts @@ -39,8 +39,8 @@ app.get('/test-transaction', async function (req, res) { const span = transaction.startChild(); - span.finish(); - transaction.finish(); + span.end(); + transaction.end(); await Sentry.flush(); diff --git a/packages/ember/addon/index.ts b/packages/ember/addon/index.ts index ef38d3c382b3..2a5da643c984 100644 --- a/packages/ember/addon/index.ts +++ b/packages/ember/addon/index.ts @@ -94,7 +94,7 @@ export const instrumentRoutePerformance = (BaseRoute origin: 'auto.ui.ember', startTimestamp, }) - .finish(); + .end(); return result; }; diff --git a/packages/ember/addon/instance-initializers/sentry-performance.ts b/packages/ember/addon/instance-initializers/sentry-performance.ts index c6c2eb9e4325..41d10842fa7c 100644 --- a/packages/ember/addon/instance-initializers/sentry-performance.ts +++ b/packages/ember/addon/instance-initializers/sentry-performance.ts @@ -132,13 +132,13 @@ export function _instrumentEmberRouter( if (nextInstance) { return; } - activeTransaction?.finish(); + activeTransaction?.end(); getBackburner().off('end', finishActiveTransaction); }; routerService.on('routeWillChange', (transition: Transition) => { const { fromRoute, toRoute } = getTransitionInformation(transition, routerService); - activeTransaction?.finish(); + activeTransaction?.end(); activeTransaction = startTransaction({ name: `route:${toRoute}`, op: 'navigation', @@ -160,10 +160,10 @@ export function _instrumentEmberRouter( if (!transitionSpan || !activeTransaction) { return; } - transitionSpan.finish(); + transitionSpan.end(); if (disableRunloopPerformance) { - activeTransaction.finish(); + activeTransaction.end(); return; } @@ -200,7 +200,7 @@ function _instrumentEmberRunloop(config: EmberSentryConfig): void { return; } if (currentQueueSpan) { - currentQueueSpan.finish(); + currentQueueSpan.end(); } currentQueueStart = timestampInSeconds(); @@ -218,7 +218,7 @@ function _instrumentEmberRunloop(config: EmberSentryConfig): void { startTimestamp: currentQueueStart, endTimestamp: now, }) - .finish(); + .end(); } currentQueueStart = undefined; } @@ -241,7 +241,7 @@ function _instrumentEmberRunloop(config: EmberSentryConfig): void { return; } if (currentQueueSpan) { - currentQueueSpan.finish(); + currentQueueSpan.end(); currentQueueSpan = undefined; } }); @@ -378,7 +378,7 @@ function _instrumentInitialLoad(config: EmberSentryConfig): void { origin: 'auto.ui.ember', startTimestamp, }); - span?.finish(endTimestamp); + span?.end(endTimestamp); performance.clearMarks(startName); performance.clearMarks(endName); diff --git a/packages/nextjs/src/client/routing/appRouterRoutingInstrumentation.ts b/packages/nextjs/src/client/routing/appRouterRoutingInstrumentation.ts index 8d45f4b9ddb3..3083013e084a 100644 --- a/packages/nextjs/src/client/routing/appRouterRoutingInstrumentation.ts +++ b/packages/nextjs/src/client/routing/appRouterRoutingInstrumentation.ts @@ -63,7 +63,7 @@ export function appRouterInstrumentation( prevLocationName = transactionName; if (activeTransaction) { - activeTransaction.finish(); + activeTransaction.end(); } startTransactionCb({ diff --git a/packages/nextjs/src/client/routing/pagesRouterRoutingInstrumentation.ts b/packages/nextjs/src/client/routing/pagesRouterRoutingInstrumentation.ts index a7c3d5bd2344..fae0624e7005 100644 --- a/packages/nextjs/src/client/routing/pagesRouterRoutingInstrumentation.ts +++ b/packages/nextjs/src/client/routing/pagesRouterRoutingInstrumentation.ts @@ -169,7 +169,7 @@ export function pagesRouterInstrumentation( prevLocationName = transactionName; if (activeTransaction) { - activeTransaction.finish(); + activeTransaction.end(); } const navigationTransaction = startTransactionCb({ @@ -193,7 +193,7 @@ export function pagesRouterInstrumentation( }); const finishRouteChangeSpan = (): void => { - nextRouteChangeSpan.finish(); + nextRouteChangeSpan.end(); Router.events.off('routeChangeComplete', finishRouteChangeSpan); }; diff --git a/packages/nextjs/src/common/utils/edgeWrapperUtils.ts b/packages/nextjs/src/common/utils/edgeWrapperUtils.ts index afdf686499c5..8763f87854d3 100644 --- a/packages/nextjs/src/common/utils/edgeWrapperUtils.ts +++ b/packages/nextjs/src/common/utils/edgeWrapperUtils.ts @@ -96,7 +96,7 @@ export function withEdgeWrapping( throw objectifiedErr; } finally { - span?.finish(); + span?.end(); currentScope?.setSpan(prevSpan); await flushQueue(); } diff --git a/packages/nextjs/src/common/utils/responseEnd.ts b/packages/nextjs/src/common/utils/responseEnd.ts index 64a3d2c59c52..e59a99fb0ebb 100644 --- a/packages/nextjs/src/common/utils/responseEnd.ts +++ b/packages/nextjs/src/common/utils/responseEnd.ts @@ -42,7 +42,7 @@ export function autoEndTransactionOnResponseEnd(transaction: Transaction, res: S export function finishTransaction(transaction: Transaction | undefined, res: ServerResponse): void { if (transaction) { transaction.setHttpStatus(res.statusCode); - transaction.finish(); + transaction.end(); } } diff --git a/packages/nextjs/src/common/utils/wrapperUtils.ts b/packages/nextjs/src/common/utils/wrapperUtils.ts index 5451b1264723..e25220ce61c2 100644 --- a/packages/nextjs/src/common/utils/wrapperUtils.ts +++ b/packages/nextjs/src/common/utils/wrapperUtils.ts @@ -162,7 +162,7 @@ export function withTracedServerSideDataFetcher Pr previousSpan?.setStatus('internal_error'); throw e; } finally { - dataFetcherSpan.finish(); + dataFetcherSpan.end(); scope.setSpan(previousSpan); if (!platformSupportsStreaming()) { await flushQueue(); @@ -219,7 +219,7 @@ export async function callDataFetcherTraced Promis // that set the transaction status, we need to manually set the status of the span & transaction transaction.setStatus('internal_error'); span.setStatus('internal_error'); - span.finish(); + span.end(); // TODO Copy more robust error handling over from `withSentry` captureException(err, { mechanism: { handled: false } }); diff --git a/packages/nextjs/test/clientSdk.test.ts b/packages/nextjs/test/clientSdk.test.ts index ebedef2506c0..1b35f82cbfe8 100644 --- a/packages/nextjs/test/clientSdk.test.ts +++ b/packages/nextjs/test/clientSdk.test.ts @@ -90,7 +90,7 @@ describe('Client init()', () => { const transportSend = jest.spyOn(hub.getClient()!.getTransport()!, 'send'); const transaction = hub.startTransaction({ name: '/404' }); - transaction.finish(); + transaction.end(); expect(transportSend).not.toHaveBeenCalled(); expect(captureEvent.mock.results[0].value).toBeUndefined(); diff --git a/packages/nextjs/test/edge/withSentryAPI.test.ts b/packages/nextjs/test/edge/withSentryAPI.test.ts index d2dbc9385c44..cd860d886826 100644 --- a/packages/nextjs/test/edge/withSentryAPI.test.ts +++ b/packages/nextjs/test/edge/withSentryAPI.test.ts @@ -91,7 +91,7 @@ describe('wrapApiHandlerWithSentry', () => { }), ); - testTransaction.finish(); + testTransaction.end(); coreSdk.getCurrentHub().getScope().setSpan(undefined); }); }); diff --git a/packages/nextjs/test/performance/pagesRouterInstrumentation.test.ts b/packages/nextjs/test/performance/pagesRouterInstrumentation.test.ts index 107f02eb9af6..592df911bde2 100644 --- a/packages/nextjs/test/performance/pagesRouterInstrumentation.test.ts +++ b/packages/nextjs/test/performance/pagesRouterInstrumentation.test.ts @@ -50,9 +50,9 @@ function createMockStartTransaction() { () => ({ startChild: () => ({ - finish: () => undefined, + end: () => undefined, }), - finish: () => undefined, + end: () => undefined, }) as Transaction, ); } diff --git a/packages/nextjs/test/serverSdk.test.ts b/packages/nextjs/test/serverSdk.test.ts index 3467f2baa548..0813d4931874 100644 --- a/packages/nextjs/test/serverSdk.test.ts +++ b/packages/nextjs/test/serverSdk.test.ts @@ -106,9 +106,9 @@ describe('Server init()', () => { const transportSend = jest.spyOn(hub.getClient()!.getTransport()!, 'send'); const transaction = hub.startTransaction({ name: '/404' }); - transaction.finish(); + transaction.end(); - // We need to flush because the event processor pipeline is async whereas transaction.finish() is sync. + // We need to flush because the event processor pipeline is async whereas transaction.end() is sync. await SentryNode.flush(); expect(transportSend).not.toHaveBeenCalled(); diff --git a/packages/node-integration-tests/suites/public-api/startTransaction/basic-usage/scenario.ts b/packages/node-integration-tests/suites/public-api/startTransaction/basic-usage/scenario.ts index c5134123351b..1e4931a2bae7 100644 --- a/packages/node-integration-tests/suites/public-api/startTransaction/basic-usage/scenario.ts +++ b/packages/node-integration-tests/suites/public-api/startTransaction/basic-usage/scenario.ts @@ -11,4 +11,4 @@ Sentry.init({ const transaction = Sentry.startTransaction({ name: 'test_transaction_1' }); -transaction.finish(); +transaction.end(); diff --git a/packages/node-integration-tests/suites/public-api/startTransaction/with-nested-spans/scenario.ts b/packages/node-integration-tests/suites/public-api/startTransaction/with-nested-spans/scenario.ts index 5fe8dd195de6..a340de7b21fe 100644 --- a/packages/node-integration-tests/suites/public-api/startTransaction/with-nested-spans/scenario.ts +++ b/packages/node-integration-tests/suites/public-api/startTransaction/with-nested-spans/scenario.ts @@ -19,7 +19,7 @@ const span_1 = transaction.startChild({ for (let i = 0; i < 2000; i++); // span_1 finishes -span_1.finish(); +span_1.end(); // span_2 doesn't finish transaction.startChild({ op: 'span_2' }); @@ -32,9 +32,9 @@ for (let i = 0; i < 4000; i++); span_3.startChild({ op: 'span_4', data: { qux: 'quux' } }); // span_5 is another child of span_3 but finishes. -span_3.startChild({ op: 'span_5' }).finish(); +span_3.startChild({ op: 'span_5' }).end(); // span_3 also finishes -span_3.finish(); +span_3.end(); -transaction.finish(); +transaction.end(); diff --git a/packages/node-integration-tests/suites/tracing-new/apollo-graphql/scenario.ts b/packages/node-integration-tests/suites/tracing-new/apollo-graphql/scenario.ts index 0c53294d1f4f..b37bd6df6fc9 100644 --- a/packages/node-integration-tests/suites/tracing-new/apollo-graphql/scenario.ts +++ b/packages/node-integration-tests/suites/tracing-new/apollo-graphql/scenario.ts @@ -38,5 +38,5 @@ Sentry.getCurrentScope().setSpan(transaction); query: '{hello}', }); - transaction.finish(); + transaction.end(); })(); diff --git a/packages/node-integration-tests/suites/tracing-new/auto-instrument/mongodb/scenario.ts b/packages/node-integration-tests/suites/tracing-new/auto-instrument/mongodb/scenario.ts index 9d747e2eff4b..36f8c3503832 100644 --- a/packages/node-integration-tests/suites/tracing-new/auto-instrument/mongodb/scenario.ts +++ b/packages/node-integration-tests/suites/tracing-new/auto-instrument/mongodb/scenario.ts @@ -36,7 +36,7 @@ async function run(): Promise { await collection.find({ title: 'South Park' }).toArray(); } finally { - if (transaction) transaction.finish(); + if (transaction) transaction.end(); await client.close(); } } diff --git a/packages/node-integration-tests/suites/tracing-new/auto-instrument/mysql/withConnect/scenario.ts b/packages/node-integration-tests/suites/tracing-new/auto-instrument/mysql/withConnect/scenario.ts index 7d94099ea30c..9b033e72a669 100644 --- a/packages/node-integration-tests/suites/tracing-new/auto-instrument/mysql/withConnect/scenario.ts +++ b/packages/node-integration-tests/suites/tracing-new/auto-instrument/mysql/withConnect/scenario.ts @@ -28,7 +28,7 @@ Sentry.getCurrentScope().setSpan(transaction); connection.query('SELECT 1 + 1 AS solution', function () { connection.query('SELECT NOW()', ['1', '2'], () => { - if (transaction) transaction.finish(); + if (transaction) transaction.end(); connection.end(); }); }); diff --git a/packages/node-integration-tests/suites/tracing-new/auto-instrument/mysql/withoutCallback/scenario.ts b/packages/node-integration-tests/suites/tracing-new/auto-instrument/mysql/withoutCallback/scenario.ts index 4b3346caed20..23d07f346875 100644 --- a/packages/node-integration-tests/suites/tracing-new/auto-instrument/mysql/withoutCallback/scenario.ts +++ b/packages/node-integration-tests/suites/tracing-new/auto-instrument/mysql/withoutCallback/scenario.ts @@ -37,7 +37,7 @@ query.on('end', () => { // Wait a bit to ensure the queries completed setTimeout(() => { - transaction.finish(); + transaction.end(); }, 500); }); }); diff --git a/packages/node-integration-tests/suites/tracing-new/auto-instrument/mysql/withoutConnect/scenario.ts b/packages/node-integration-tests/suites/tracing-new/auto-instrument/mysql/withoutConnect/scenario.ts index 2e13bf49b9ac..bf9e4bf90e35 100644 --- a/packages/node-integration-tests/suites/tracing-new/auto-instrument/mysql/withoutConnect/scenario.ts +++ b/packages/node-integration-tests/suites/tracing-new/auto-instrument/mysql/withoutConnect/scenario.ts @@ -22,7 +22,7 @@ Sentry.getCurrentScope().setSpan(transaction); connection.query('SELECT 1 + 1 AS solution', function () { connection.query('SELECT NOW()', ['1', '2'], () => { - if (transaction) transaction.finish(); + if (transaction) transaction.end(); connection.end(); }); }); diff --git a/packages/node-integration-tests/suites/tracing-new/auto-instrument/pg/scenario.ts b/packages/node-integration-tests/suites/tracing-new/auto-instrument/pg/scenario.ts index c10661094981..b41be87c9550 100644 --- a/packages/node-integration-tests/suites/tracing-new/auto-instrument/pg/scenario.ts +++ b/packages/node-integration-tests/suites/tracing-new/auto-instrument/pg/scenario.ts @@ -18,6 +18,6 @@ Sentry.getCurrentScope().setSpan(transaction); const client = new pg.Client(); client.query('SELECT * FROM foo where bar ilike "baz%"', ['a', 'b'], () => client.query('SELECT * FROM bazz', () => { - client.query('SELECT NOW()', () => transaction.finish()); + client.query('SELECT NOW()', () => transaction.end()); }), ); diff --git a/packages/node-integration-tests/suites/tracing-new/prisma-orm/scenario.ts b/packages/node-integration-tests/suites/tracing-new/prisma-orm/scenario.ts index ee73dc922747..20847871e7a1 100644 --- a/packages/node-integration-tests/suites/tracing-new/prisma-orm/scenario.ts +++ b/packages/node-integration-tests/suites/tracing-new/prisma-orm/scenario.ts @@ -38,7 +38,7 @@ async function run(): Promise { }, }); } finally { - if (transaction) transaction.finish(); + if (transaction) transaction.end(); } } diff --git a/packages/node-integration-tests/suites/tracing-new/tracePropagationTargets/scenario.ts b/packages/node-integration-tests/suites/tracing-new/tracePropagationTargets/scenario.ts index d1eb5fe017ed..7c86686cbba8 100644 --- a/packages/node-integration-tests/suites/tracing-new/tracePropagationTargets/scenario.ts +++ b/packages/node-integration-tests/suites/tracing-new/tracePropagationTargets/scenario.ts @@ -19,4 +19,4 @@ http.get('http://match-this-url.com/api/v1'); http.get('http://dont-match-this-url.com/api/v2'); http.get('http://dont-match-this-url.com/api/v3'); -transaction.finish(); +transaction.end(); diff --git a/packages/node-integration-tests/suites/tracing/apollo-graphql/scenario.ts b/packages/node-integration-tests/suites/tracing/apollo-graphql/scenario.ts index 0e5e0bd9edd0..7b34ffab0613 100644 --- a/packages/node-integration-tests/suites/tracing/apollo-graphql/scenario.ts +++ b/packages/node-integration-tests/suites/tracing/apollo-graphql/scenario.ts @@ -40,5 +40,5 @@ Sentry.getCurrentScope().setSpan(transaction); query: '{hello}', }); - transaction.finish(); + transaction.end(); })(); diff --git a/packages/node-integration-tests/suites/tracing/auto-instrument/mongodb/scenario.ts b/packages/node-integration-tests/suites/tracing/auto-instrument/mongodb/scenario.ts index 7979ea57483b..cff8329d22a3 100644 --- a/packages/node-integration-tests/suites/tracing/auto-instrument/mongodb/scenario.ts +++ b/packages/node-integration-tests/suites/tracing/auto-instrument/mongodb/scenario.ts @@ -37,7 +37,7 @@ async function run(): Promise { await collection.find({ title: 'South Park' }).toArray(); } finally { - if (transaction) transaction.finish(); + if (transaction) transaction.end(); await client.close(); } } diff --git a/packages/node-integration-tests/suites/tracing/auto-instrument/mysql/scenario.ts b/packages/node-integration-tests/suites/tracing/auto-instrument/mysql/scenario.ts index 2cf161c0ab78..30f9fb368b3a 100644 --- a/packages/node-integration-tests/suites/tracing/auto-instrument/mysql/scenario.ts +++ b/packages/node-integration-tests/suites/tracing/auto-instrument/mysql/scenario.ts @@ -29,7 +29,7 @@ Sentry.getCurrentScope().setSpan(transaction); connection.query('SELECT 1 + 1 AS solution', function () { connection.query('SELECT NOW()', ['1', '2'], () => { - if (transaction) transaction.finish(); + if (transaction) transaction.end(); connection.end(); }); }); diff --git a/packages/node-integration-tests/suites/tracing/auto-instrument/pg/scenario.ts b/packages/node-integration-tests/suites/tracing/auto-instrument/pg/scenario.ts index c39069909082..95248c82f075 100644 --- a/packages/node-integration-tests/suites/tracing/auto-instrument/pg/scenario.ts +++ b/packages/node-integration-tests/suites/tracing/auto-instrument/pg/scenario.ts @@ -19,6 +19,6 @@ Sentry.getCurrentScope().setSpan(transaction); const client = new pg.Client(); client.query('SELECT * FROM foo where bar ilike "baz%"', ['a', 'b'], () => client.query('SELECT * FROM bazz', () => { - client.query('SELECT NOW()', () => transaction.finish()); + client.query('SELECT NOW()', () => transaction.end()); }), ); diff --git a/packages/node-integration-tests/suites/tracing/prisma-orm/scenario.ts b/packages/node-integration-tests/suites/tracing/prisma-orm/scenario.ts index 578c5802fea0..7e8a7c6eca5f 100644 --- a/packages/node-integration-tests/suites/tracing/prisma-orm/scenario.ts +++ b/packages/node-integration-tests/suites/tracing/prisma-orm/scenario.ts @@ -40,7 +40,7 @@ async function run(): Promise { }, }); } finally { - if (transaction) transaction.finish(); + if (transaction) transaction.end(); } } diff --git a/packages/node-integration-tests/suites/tracing/tracePropagationTargets/scenario.ts b/packages/node-integration-tests/suites/tracing/tracePropagationTargets/scenario.ts index c07faeeb9a3f..9fdeba1fcb95 100644 --- a/packages/node-integration-tests/suites/tracing/tracePropagationTargets/scenario.ts +++ b/packages/node-integration-tests/suites/tracing/tracePropagationTargets/scenario.ts @@ -21,4 +21,4 @@ http.get('http://match-this-url.com/api/v1'); http.get('http://dont-match-this-url.com/api/v2'); http.get('http://dont-match-this-url.com/api/v3'); -transaction.finish(); +transaction.end(); diff --git a/packages/node/src/handlers.ts b/packages/node/src/handlers.ts index 832d87139f83..857e6c4892d5 100644 --- a/packages/node/src/handlers.ts +++ b/packages/node/src/handlers.ts @@ -98,7 +98,7 @@ export function tracingHandler(): ( setImmediate(() => { addRequestDataToTransaction(transaction, req); transaction.setHttpStatus(res.statusCode); - transaction.finish(); + transaction.end(); }); }); diff --git a/packages/node/src/integrations/hapi/index.ts b/packages/node/src/integrations/hapi/index.ts index 5e158af810ca..d63b831da4e2 100644 --- a/packages/node/src/integrations/hapi/index.ts +++ b/packages/node/src/integrations/hapi/index.ts @@ -53,7 +53,7 @@ export const hapiErrorPlugin = { if (transaction) { transaction.setStatus('internal_error'); - transaction.finish(); + transaction.end(); } }); }, @@ -114,7 +114,7 @@ export const hapiTracingPlugin = { } if (transaction) { - transaction.finish(); + transaction.end(); } return h.continue; diff --git a/packages/node/src/integrations/http.ts b/packages/node/src/integrations/http.ts index 02e79d06b942..5d6b8857f93b 100644 --- a/packages/node/src/integrations/http.ts +++ b/packages/node/src/integrations/http.ts @@ -292,7 +292,7 @@ function _createWrappedRequestMethodFactory( requestSpan.setHttpStatus(res.statusCode); } requestSpan.description = cleanSpanDescription(requestSpan.description, requestOptions, req); - requestSpan.finish(); + requestSpan.end(); } }) .once('error', function (this: http.ClientRequest): void { @@ -305,7 +305,7 @@ function _createWrappedRequestMethodFactory( if (requestSpan) { requestSpan.setHttpStatus(500); requestSpan.description = cleanSpanDescription(requestSpan.description, requestOptions, req); - requestSpan.finish(); + requestSpan.end(); } }); }; diff --git a/packages/node/src/integrations/undici/index.ts b/packages/node/src/integrations/undici/index.ts index b67562843d84..4f67993f7321 100644 --- a/packages/node/src/integrations/undici/index.ts +++ b/packages/node/src/integrations/undici/index.ts @@ -211,7 +211,7 @@ export class Undici implements Integration { const span = request.__sentry_span__; if (span) { span.setHttpStatus(response.statusCode); - span.finish(); + span.end(); } if (this._options.breadcrumbs) { @@ -251,7 +251,7 @@ export class Undici implements Integration { const span = request.__sentry_span__; if (span) { span.setStatus('internal_error'); - span.finish(); + span.end(); } if (this._options.breadcrumbs) { diff --git a/packages/node/test/handlers.test.ts b/packages/node/test/handlers.test.ts index cf6dab4d9338..14de421db5f7 100644 --- a/packages/node/test/handlers.test.ts +++ b/packages/node/test/handlers.test.ts @@ -362,7 +362,7 @@ describe('tracingHandler', () => { it('pulls status code from the response', done => { const transaction = new Transaction({ name: 'mockTransaction' }); jest.spyOn(sentryCore, 'startTransaction').mockReturnValue(transaction as Transaction); - const finishTransaction = jest.spyOn(transaction, 'finish'); + const finishTransaction = jest.spyOn(transaction, 'end'); sentryTracingMiddleware(req, res, next); res.statusCode = 200; @@ -410,7 +410,7 @@ describe('tracingHandler', () => { it('closes the transaction when request processing is done', done => { const transaction = new Transaction({ name: 'mockTransaction' }); jest.spyOn(sentryCore, 'startTransaction').mockReturnValue(transaction as Transaction); - const finishTransaction = jest.spyOn(transaction, 'finish'); + const finishTransaction = jest.spyOn(transaction, 'end'); sentryTracingMiddleware(req, res, next); res.emit('finish'); @@ -421,7 +421,7 @@ describe('tracingHandler', () => { }); }); - it('waits to finish transaction until all spans are finished, even though `transaction.finish()` is registered on `res.finish` event first', done => { + it('waits to finish transaction until all spans are finished, even though `transaction.end()` is registered on `res.finish` event first', done => { const transaction = new Transaction({ name: 'mockTransaction', sampled: true }); transaction.initSpanRecorder(); const span = transaction.startChild({ @@ -429,8 +429,8 @@ describe('tracingHandler', () => { op: 'middleware', }); jest.spyOn(sentryCore, 'startTransaction').mockReturnValue(transaction as Transaction); - const finishSpan = jest.spyOn(span, 'finish'); - const finishTransaction = jest.spyOn(transaction, 'finish'); + const finishSpan = jest.spyOn(span, 'end'); + const finishTransaction = jest.spyOn(transaction, 'end'); let sentEvent: Event; jest.spyOn((transaction as any)._hub, 'captureEvent').mockImplementation(event => { @@ -439,7 +439,7 @@ describe('tracingHandler', () => { sentryTracingMiddleware(req, res, next); res.once('finish', () => { - span.finish(); + span.end(); }); res.emit('finish'); diff --git a/packages/opentelemetry-node/src/spanprocessor.ts b/packages/opentelemetry-node/src/spanprocessor.ts index 772bd861cc2a..f220d5893e93 100644 --- a/packages/opentelemetry-node/src/spanprocessor.ts +++ b/packages/opentelemetry-node/src/spanprocessor.ts @@ -124,7 +124,7 @@ export class SentrySpanProcessor implements OtelSpanProcessor { // Ensure we do not capture any OTEL spans for finishing (and sending) this context.with(suppressTracing(context.active()), () => { - sentrySpan.finish(convertOtelTimeToSeconds(otelSpan.endTime)); + sentrySpan.end(convertOtelTimeToSeconds(otelSpan.endTime)); }); clearSpan(otelSpanId); diff --git a/packages/opentelemetry/src/spanExporter.ts b/packages/opentelemetry/src/spanExporter.ts index c15bd4483a9b..fdb63636452f 100644 --- a/packages/opentelemetry/src/spanExporter.ts +++ b/packages/opentelemetry/src/spanExporter.ts @@ -222,7 +222,7 @@ function createAndFinishSpanForOtelSpan(node: SpanNode, sentryParentSpan: Sentry createAndFinishSpanForOtelSpan(child, sentrySpan, remaining); }); - sentrySpan.finish(convertOtelTimeToSeconds(span.endTime)); + sentrySpan.end(convertOtelTimeToSeconds(span.endTime)); } function getSpanData(span: ReadableSpan): { diff --git a/packages/react/src/profiler.tsx b/packages/react/src/profiler.tsx index 9647d34f0fb4..11ae1e83dabf 100644 --- a/packages/react/src/profiler.tsx +++ b/packages/react/src/profiler.tsx @@ -70,7 +70,7 @@ class Profiler extends React.Component { // If a component mounted, we can finish the mount activity. public componentDidMount(): void { if (this._mountSpan) { - this._mountSpan.finish(); + this._mountSpan.end(); } } @@ -101,7 +101,7 @@ class Profiler extends React.Component { public componentDidUpdate(): void { if (this._updateSpan) { - this._updateSpan.finish(); + this._updateSpan.end(); this._updateSpan = undefined; } } @@ -192,7 +192,7 @@ function useProfiler( React.useEffect(() => { if (mountSpan) { - mountSpan.finish(); + mountSpan.end(); } return (): void => { diff --git a/packages/react/src/reactrouter.tsx b/packages/react/src/reactrouter.tsx index 9e7077c59898..3234cdc7871d 100644 --- a/packages/react/src/reactrouter.tsx +++ b/packages/react/src/reactrouter.tsx @@ -105,7 +105,7 @@ function createReactRouterInstrumentation( history.listen((location, action) => { if (action && (action === 'PUSH' || action === 'POP')) { if (activeTransaction) { - activeTransaction.finish(); + activeTransaction.end(); } const [name, source] = normalizeTransactionName(location.pathname); diff --git a/packages/react/src/reactrouterv3.ts b/packages/react/src/reactrouterv3.ts index f185a025a649..db1ce1320508 100644 --- a/packages/react/src/reactrouterv3.ts +++ b/packages/react/src/reactrouterv3.ts @@ -69,7 +69,7 @@ export function reactRouterV3Instrumentation( history.listen(location => { if (location.action === 'PUSH' || location.action === 'POP') { if (activeTransaction) { - activeTransaction.finish(); + activeTransaction.end(); } const tags: Record = { 'routing.instrumentation': 'react-router-v3', diff --git a/packages/react/src/reactrouterv6.tsx b/packages/react/src/reactrouterv6.tsx index 98cac5294ead..14c975a90105 100644 --- a/packages/react/src/reactrouterv6.tsx +++ b/packages/react/src/reactrouterv6.tsx @@ -149,7 +149,7 @@ function handleNavigation( if (_startTransactionOnLocationChange && (navigationType === 'PUSH' || navigationType === 'POP') && branches) { if (activeTransaction) { - activeTransaction.finish(); + activeTransaction.end(); } const [name, source] = getNormalizedName(routes, location, branches, basename); diff --git a/packages/react/test/profiler.test.tsx b/packages/react/test/profiler.test.tsx index 70eaff2d2c8b..847d2e4603ed 100644 --- a/packages/react/test/profiler.test.tsx +++ b/packages/react/test/profiler.test.tsx @@ -18,7 +18,7 @@ class MockSpan { return new MockSpan(ctx); } - public finish(): void { + public end(): void { mockFinish(); } } diff --git a/packages/react/test/reactrouterv3.test.tsx b/packages/react/test/reactrouterv3.test.tsx index dad1b4793d26..21b9054e45ce 100644 --- a/packages/react/test/reactrouterv3.test.tsx +++ b/packages/react/test/reactrouterv3.test.tsx @@ -19,7 +19,7 @@ declare module 'react-router-3' { function createMockStartTransaction(opts: { finish?: jest.FunctionLike; setMetadata?: jest.FunctionLike } = {}) { const { finish = jest.fn(), setMetadata = jest.fn() } = opts; return jest.fn().mockReturnValue({ - finish, + end: finish, setMetadata, }); } diff --git a/packages/react/test/reactrouterv4.test.tsx b/packages/react/test/reactrouterv4.test.tsx index e1c8a71e66b0..1d3d4df4f170 100644 --- a/packages/react/test/reactrouterv4.test.tsx +++ b/packages/react/test/reactrouterv4.test.tsx @@ -22,7 +22,7 @@ describe('React Router v4', () => { const history = createMemoryHistory(); const mockFinish = jest.fn(); const mockSetName = jest.fn(); - const mockStartTransaction = jest.fn().mockReturnValue({ setName: mockSetName, finish: mockFinish }); + const mockStartTransaction = jest.fn().mockReturnValue({ setName: mockSetName, end: mockFinish }); reactRouterV4Instrumentation(history, options.routes, options.matchPath)( mockStartTransaction, options.startTransactionOnPageLoad, diff --git a/packages/react/test/reactrouterv5.test.tsx b/packages/react/test/reactrouterv5.test.tsx index 3ab94aea0401..e61306bc8b40 100644 --- a/packages/react/test/reactrouterv5.test.tsx +++ b/packages/react/test/reactrouterv5.test.tsx @@ -22,7 +22,7 @@ describe('React Router v5', () => { const history = createMemoryHistory(); const mockFinish = jest.fn(); const mockSetName = jest.fn(); - const mockStartTransaction = jest.fn().mockReturnValue({ setName: mockSetName, finish: mockFinish }); + const mockStartTransaction = jest.fn().mockReturnValue({ setName: mockSetName, end: mockFinish }); reactRouterV5Instrumentation(history, options.routes, options.matchPath)( mockStartTransaction, options.startTransactionOnPageLoad, diff --git a/packages/react/test/reactrouterv6.4.test.tsx b/packages/react/test/reactrouterv6.4.test.tsx index f97b9a82253a..5c2c9e7b3d5b 100644 --- a/packages/react/test/reactrouterv6.4.test.tsx +++ b/packages/react/test/reactrouterv6.4.test.tsx @@ -34,7 +34,7 @@ describe('React Router v6.4', () => { }; const mockFinish = jest.fn(); const mockSetName = jest.fn(); - const mockStartTransaction = jest.fn().mockReturnValue({ setName: mockSetName, finish: mockFinish }); + const mockStartTransaction = jest.fn().mockReturnValue({ setName: mockSetName, end: mockFinish }); reactRouterV6Instrumentation( React.useEffect, diff --git a/packages/react/test/reactrouterv6.test.tsx b/packages/react/test/reactrouterv6.test.tsx index 86f6ae9b66e0..fd6ad444125e 100644 --- a/packages/react/test/reactrouterv6.test.tsx +++ b/packages/react/test/reactrouterv6.test.tsx @@ -30,7 +30,7 @@ describe('React Router v6', () => { }; const mockFinish = jest.fn(); const mockSetName = jest.fn(); - const mockStartTransaction = jest.fn().mockReturnValue({ setName: mockSetName, finish: mockFinish }); + const mockStartTransaction = jest.fn().mockReturnValue({ setName: mockSetName, end: mockFinish }); reactRouterV6Instrumentation( React.useEffect, diff --git a/packages/remix/src/client/performance.tsx b/packages/remix/src/client/performance.tsx index 2e597d10fa2b..af6344165b6a 100644 --- a/packages/remix/src/client/performance.tsx +++ b/packages/remix/src/client/performance.tsx @@ -134,7 +134,7 @@ export function withSentry

, R extends React.Co _useEffect(() => { if (isBaseLocation) { if (activeTransaction) { - activeTransaction.finish(); + activeTransaction.end(); } return; @@ -142,7 +142,7 @@ export function withSentry

, R extends React.Co if (_startTransactionOnLocationChange && matches && matches.length) { if (activeTransaction) { - activeTransaction.finish(); + activeTransaction.end(); } activeTransaction = _customStartTransaction({ diff --git a/packages/remix/src/utils/instrumentServer.ts b/packages/remix/src/utils/instrumentServer.ts index 36f41968edb5..90f72296d2a1 100644 --- a/packages/remix/src/utils/instrumentServer.ts +++ b/packages/remix/src/utils/instrumentServer.ts @@ -198,7 +198,7 @@ function makeWrappedDocumentRequestFunction(remixVersion?: number) { loadContext, ); - span?.finish(); + span?.end(); } catch (err) { const isRemixV1 = !FUTURE_FLAGS?.v2_errorBoundary && remixVersion !== 2; @@ -246,7 +246,7 @@ function makeWrappedDataFunction( res = await origFn.call(this, args); currentScope.setSpan(activeTransaction); - span?.finish(); + span?.end(); } catch (err) { const isRemixV2 = FUTURE_FLAGS?.v2_errorBoundary || remixVersion === 2; @@ -463,7 +463,7 @@ function wrapRequestHandler(origRequestHandler: RequestHandler, build: ServerBui transaction.setHttpStatus(res.status); } - transaction.finish(); + transaction.end(); return res; }); diff --git a/packages/remix/src/utils/serverAdapters/express.ts b/packages/remix/src/utils/serverAdapters/express.ts index b60b74a8e0ff..ea765d35a353 100644 --- a/packages/remix/src/utils/serverAdapters/express.ts +++ b/packages/remix/src/utils/serverAdapters/express.ts @@ -143,7 +143,7 @@ async function finishSentryProcessing(res: AugmentedExpressResponse): Promise(resolve => { setImmediate(() => { - transaction.finish(); + transaction.end(); resolve(); }); }); diff --git a/packages/remix/test/integration/common/routes/manual-tracing.$id.tsx b/packages/remix/test/integration/common/routes/manual-tracing.$id.tsx index 2f925881b9cf..a7383f1b8f5a 100644 --- a/packages/remix/test/integration/common/routes/manual-tracing.$id.tsx +++ b/packages/remix/test/integration/common/routes/manual-tracing.$id.tsx @@ -2,6 +2,6 @@ import * as Sentry from '@sentry/remix'; export default function ManualTracing() { const transaction = Sentry.startTransaction({ name: 'test_transaction_1' }); - transaction.finish(); + transaction.end(); return

; } diff --git a/packages/serverless/src/awslambda.ts b/packages/serverless/src/awslambda.ts index 3f6ed2ad0ef8..9094709082dc 100644 --- a/packages/serverless/src/awslambda.ts +++ b/packages/serverless/src/awslambda.ts @@ -342,7 +342,7 @@ export function wrapHandler( throw e; } finally { clearTimeout(timeoutWarningTimer); - transaction?.finish(); + transaction?.end(); await flush(options.flushTimeout).catch(e => { DEBUG_BUILD && logger.error(e); }); diff --git a/packages/serverless/src/awsservices.ts b/packages/serverless/src/awsservices.ts index 33a3a25b8689..e7404b0695c4 100644 --- a/packages/serverless/src/awsservices.ts +++ b/packages/serverless/src/awsservices.ts @@ -71,7 +71,7 @@ function wrapMakeRequest( }); req.on('complete', () => { if (span) { - span.finish(); + span.end(); } }); diff --git a/packages/serverless/src/gcpfunction/cloud_events.ts b/packages/serverless/src/gcpfunction/cloud_events.ts index 0e89216a2fd7..547cf93b3a5f 100644 --- a/packages/serverless/src/gcpfunction/cloud_events.ts +++ b/packages/serverless/src/gcpfunction/cloud_events.ts @@ -52,7 +52,7 @@ function _wrapCloudEventFunction( if (args[0] !== null && args[0] !== undefined) { captureException(args[0], scope => markEventUnhandled(scope)); } - transaction?.finish(); + transaction?.end(); // eslint-disable-next-line @typescript-eslint/no-floating-promises flush(options.flushTimeout) diff --git a/packages/serverless/src/gcpfunction/events.ts b/packages/serverless/src/gcpfunction/events.ts index b69335b272d7..e3f6b30a4525 100644 --- a/packages/serverless/src/gcpfunction/events.ts +++ b/packages/serverless/src/gcpfunction/events.ts @@ -54,7 +54,7 @@ function _wrapEventFunction if (args[0] !== null && args[0] !== undefined) { captureException(args[0], scope => markEventUnhandled(scope)); } - transaction?.finish(); + transaction?.end(); // eslint-disable-next-line @typescript-eslint/no-floating-promises flush(options.flushTimeout) diff --git a/packages/serverless/src/gcpfunction/http.ts b/packages/serverless/src/gcpfunction/http.ts index 726f56c91a52..50bbcd76e782 100644 --- a/packages/serverless/src/gcpfunction/http.ts +++ b/packages/serverless/src/gcpfunction/http.ts @@ -108,7 +108,7 @@ function _wrapHttpFunction(fn: HttpFunction, wrapOptions: Partial void), encoding?: string | (() => void), cb?: () => void): any { transaction?.setHttpStatus(res.statusCode); - transaction?.finish(); + transaction?.end(); // eslint-disable-next-line @typescript-eslint/no-floating-promises flush(options.flushTimeout) diff --git a/packages/serverless/src/google-cloud-grpc.ts b/packages/serverless/src/google-cloud-grpc.ts index d475d9b3b421..9f2ea37203b4 100644 --- a/packages/serverless/src/google-cloud-grpc.ts +++ b/packages/serverless/src/google-cloud-grpc.ts @@ -119,7 +119,7 @@ function fillGrpcFunction(stub: Stub, serviceIdentifier: string, methodName: str } ret.on('status', () => { if (span) { - span.finish(); + span.end(); } }); return ret; diff --git a/packages/serverless/src/google-cloud-http.ts b/packages/serverless/src/google-cloud-http.ts index f9eb9a6cc3cd..6b522facf5ae 100644 --- a/packages/serverless/src/google-cloud-http.ts +++ b/packages/serverless/src/google-cloud-http.ts @@ -64,7 +64,7 @@ function wrapRequestFunction(orig: RequestFunction): RequestFunction { } orig.call(this, reqOpts, (...args: Parameters) => { if (span) { - span.finish(); + span.end(); } callback(...args); }); diff --git a/packages/serverless/test/__mocks__/@sentry/node.ts b/packages/serverless/test/__mocks__/@sentry/node.ts index f9322057f1d5..0dbf38c3d483 100644 --- a/packages/serverless/test/__mocks__/@sentry/node.ts +++ b/packages/serverless/test/__mocks__/@sentry/node.ts @@ -25,10 +25,10 @@ export const fakeScope = { setPropagationContext: jest.fn(), }; export const fakeSpan = { - finish: jest.fn(), + end: jest.fn(), }; export const fakeTransaction = { - finish: jest.fn(), + end: jest.fn(), setHttpStatus: jest.fn(), startChild: jest.fn(() => fakeSpan), }; @@ -45,9 +45,9 @@ export const getClient = jest.fn(() => ({})); export const resetMocks = (): void => { fakeTransaction.setHttpStatus.mockClear(); - fakeTransaction.finish.mockClear(); + fakeTransaction.end.mockClear(); fakeTransaction.startChild.mockClear(); - fakeSpan.finish.mockClear(); + fakeSpan.end.mockClear(); fakeHub.configureScope.mockClear(); fakeHub.pushScope.mockClear(); fakeHub.popScope.mockClear(); diff --git a/packages/serverless/test/awslambda.test.ts b/packages/serverless/test/awslambda.test.ts index 5c67c8481d4a..49f41e67f6fd 100644 --- a/packages/serverless/test/awslambda.test.ts +++ b/packages/serverless/test/awslambda.test.ts @@ -219,7 +219,7 @@ describe('AWSLambda', () => { expect(SentryNode.fakeHub.startTransaction).toBeCalledWith(fakeTransactionContext); expectScopeSettings(fakeTransactionContext); // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.finish).toBeCalled(); + expect(SentryNode.fakeTransaction.end).toBeCalled(); expect(SentryNode.flush).toBeCalledWith(2000); }); @@ -247,7 +247,7 @@ describe('AWSLambda', () => { expectScopeSettings(fakeTransactionContext); expect(SentryNode.captureException).toBeCalledWith(error, expect.any(Function)); // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.finish).toBeCalled(); + expect(SentryNode.fakeTransaction.end).toBeCalled(); expect(SentryNode.flush).toBeCalledWith(2000); } }); @@ -326,7 +326,7 @@ describe('AWSLambda', () => { expectScopeSettings(fakeTransactionContext); expect(SentryNode.captureException).toBeCalledWith(e, expect.any(Function)); // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.finish).toBeCalled(); + expect(SentryNode.fakeTransaction.end).toBeCalled(); expect(SentryNode.flush).toBeCalled(); } }); @@ -354,7 +354,7 @@ describe('AWSLambda', () => { expect(SentryNode.fakeHub.startTransaction).toBeCalledWith(fakeTransactionContext); expectScopeSettings(fakeTransactionContext); // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.finish).toBeCalled(); + expect(SentryNode.fakeTransaction.end).toBeCalled(); expect(SentryNode.flush).toBeCalled(); }); @@ -393,7 +393,7 @@ describe('AWSLambda', () => { expectScopeSettings(fakeTransactionContext); expect(SentryNode.captureException).toBeCalledWith(error, expect.any(Function)); // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.finish).toBeCalled(); + expect(SentryNode.fakeTransaction.end).toBeCalled(); expect(SentryNode.flush).toBeCalled(); } }); @@ -436,7 +436,7 @@ describe('AWSLambda', () => { expect(SentryNode.fakeHub.startTransaction).toBeCalledWith(fakeTransactionContext); expectScopeSettings(fakeTransactionContext); // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.finish).toBeCalled(); + expect(SentryNode.fakeTransaction.end).toBeCalled(); expect(SentryNode.flush).toBeCalled(); }); @@ -475,7 +475,7 @@ describe('AWSLambda', () => { expectScopeSettings(fakeTransactionContext); expect(SentryNode.captureException).toBeCalledWith(error, expect.any(Function)); // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.finish).toBeCalled(); + expect(SentryNode.fakeTransaction.end).toBeCalled(); expect(SentryNode.flush).toBeCalled(); } }); diff --git a/packages/serverless/test/awsservices.test.ts b/packages/serverless/test/awsservices.test.ts index cca793549c99..e4abda7c9364 100644 --- a/packages/serverless/test/awsservices.test.ts +++ b/packages/serverless/test/awsservices.test.ts @@ -37,7 +37,7 @@ describe('AWSServices', () => { description: 'aws.s3.getObject foo', }); // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeSpan.finish).toBeCalled(); + expect(SentryNode.fakeSpan.end).toBeCalled(); }); test('getObject with callback', done => { diff --git a/packages/serverless/test/gcpfunction.test.ts b/packages/serverless/test/gcpfunction.test.ts index f60c26c00986..4f442c543678 100644 --- a/packages/serverless/test/gcpfunction.test.ts +++ b/packages/serverless/test/gcpfunction.test.ts @@ -127,7 +127,7 @@ describe('GCPFunction', () => { // @ts-expect-error see "Why @ts-expect-error" note expect(SentryNode.fakeTransaction.setHttpStatus).toBeCalledWith(200); // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.finish).toBeCalled(); + expect(SentryNode.fakeTransaction.end).toBeCalled(); expect(SentryNode.flush).toBeCalledWith(2000); }); @@ -197,7 +197,7 @@ describe('GCPFunction', () => { expect(SentryNode.fakeScope.setSpan).toBeCalledWith(fakeTransaction); expect(SentryNode.captureException).toBeCalledWith(error, expect.any(Function)); // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.finish).toBeCalled(); + expect(SentryNode.fakeTransaction.end).toBeCalled(); expect(SentryNode.flush).toBeCalled(); }); @@ -284,7 +284,7 @@ describe('GCPFunction', () => { // @ts-expect-error see "Why @ts-expect-error" note expect(SentryNode.fakeScope.setSpan).toBeCalledWith(fakeTransaction); // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.finish).toBeCalled(); + expect(SentryNode.fakeTransaction.end).toBeCalled(); expect(SentryNode.flush).toBeCalledWith(2000); }); @@ -313,7 +313,7 @@ describe('GCPFunction', () => { expect(SentryNode.fakeScope.setSpan).toBeCalledWith(fakeTransaction); expect(SentryNode.captureException).toBeCalledWith(error, expect.any(Function)); // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.finish).toBeCalled(); + expect(SentryNode.fakeTransaction.end).toBeCalled(); expect(SentryNode.flush).toBeCalled(); }); }); @@ -345,7 +345,7 @@ describe('GCPFunction', () => { // @ts-expect-error see "Why @ts-expect-error" note expect(SentryNode.fakeScope.setSpan).toBeCalledWith(fakeTransaction); // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.finish).toBeCalled(); + expect(SentryNode.fakeTransaction.end).toBeCalled(); expect(SentryNode.flush).toBeCalledWith(2000); }); @@ -378,7 +378,7 @@ describe('GCPFunction', () => { expect(SentryNode.fakeScope.setSpan).toBeCalledWith(fakeTransaction); expect(SentryNode.captureException).toBeCalledWith(error, expect.any(Function)); // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.finish).toBeCalled(); + expect(SentryNode.fakeTransaction.end).toBeCalled(); expect(SentryNode.flush).toBeCalled(); }); }); @@ -407,7 +407,7 @@ describe('GCPFunction', () => { // @ts-expect-error see "Why @ts-expect-error" note expect(SentryNode.fakeScope.setSpan).toBeCalledWith(fakeTransaction); // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.finish).toBeCalled(); + expect(SentryNode.fakeTransaction.end).toBeCalled(); expect(SentryNode.flush).toBeCalledWith(2000); }); @@ -436,7 +436,7 @@ describe('GCPFunction', () => { expect(SentryNode.fakeScope.setSpan).toBeCalledWith(fakeTransaction); expect(SentryNode.captureException).toBeCalledWith(error, expect.any(Function)); // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.finish).toBeCalled(); + expect(SentryNode.fakeTransaction.end).toBeCalled(); expect(SentryNode.flush).toBeCalled(); }); @@ -530,7 +530,7 @@ describe('GCPFunction', () => { // @ts-expect-error see "Why @ts-expect-error" note expect(SentryNode.fakeScope.setSpan).toBeCalledWith(fakeTransaction); // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.finish).toBeCalled(); + expect(SentryNode.fakeTransaction.end).toBeCalled(); expect(SentryNode.flush).toBeCalledWith(2000); }); @@ -559,7 +559,7 @@ describe('GCPFunction', () => { expect(SentryNode.fakeScope.setSpan).toBeCalledWith(fakeTransaction); expect(SentryNode.captureException).toBeCalledWith(error, expect.any(Function)); // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.finish).toBeCalled(); + expect(SentryNode.fakeTransaction.end).toBeCalled(); expect(SentryNode.flush).toBeCalled(); }); }); @@ -588,7 +588,7 @@ describe('GCPFunction', () => { // @ts-expect-error see "Why @ts-expect-error" note expect(SentryNode.fakeScope.setSpan).toBeCalledWith(fakeTransaction); // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.finish).toBeCalled(); + expect(SentryNode.fakeTransaction.end).toBeCalled(); expect(SentryNode.flush).toBeCalledWith(2000); }); @@ -617,7 +617,7 @@ describe('GCPFunction', () => { expect(SentryNode.fakeScope.setSpan).toBeCalledWith(fakeTransaction); expect(SentryNode.captureException).toBeCalledWith(error, expect.any(Function)); // @ts-expect-error see "Why @ts-expect-error" note - expect(SentryNode.fakeTransaction.finish).toBeCalled(); + expect(SentryNode.fakeTransaction.end).toBeCalled(); expect(SentryNode.flush).toBeCalled(); }); diff --git a/packages/svelte/src/performance.ts b/packages/svelte/src/performance.ts index 0afd5250a06f..e579b453f033 100644 --- a/packages/svelte/src/performance.ts +++ b/packages/svelte/src/performance.ts @@ -54,7 +54,7 @@ function recordInitSpan(transaction: Transaction, componentName: string): Span { }); onMount(() => { - initSpan.finish(); + initSpan.end(); }); return initSpan; @@ -86,7 +86,7 @@ function recordUpdateSpans(componentName: string, initSpan?: Span): void { if (!updateSpan) { return; } - updateSpan.finish(); + updateSpan.end(); updateSpan = undefined; }); } diff --git a/packages/svelte/test/performance.test.ts b/packages/svelte/test/performance.test.ts index e872ee7a283d..bde6b7a734db 100644 --- a/packages/svelte/test/performance.test.ts +++ b/packages/svelte/test/performance.test.ts @@ -6,15 +6,15 @@ import DummyComponent from './components/Dummy.svelte'; let returnUndefinedTransaction = false; -const testTransaction: { spans: any[]; startChild: jest.Mock; finish: jest.Mock } = { +const testTransaction: { spans: any[]; startChild: jest.Mock; end: jest.Mock } = { spans: [], startChild: jest.fn(), - finish: jest.fn(), + end: jest.fn(), }; -const testUpdateSpan = { finish: jest.fn() }; +const testUpdateSpan = { end: jest.fn() }; const testInitSpan: any = { transaction: testTransaction, - finish: jest.fn(), + end: jest.fn(), startChild: jest.fn(), }; @@ -47,7 +47,7 @@ describe('Sentry.trackComponent()', () => { return testUpdateSpan; }); - testInitSpan.finish = jest.fn(); + testInitSpan.end = jest.fn(); testInitSpan.endTimestamp = undefined; returnUndefinedTransaction = false; }); @@ -67,14 +67,14 @@ describe('Sentry.trackComponent()', () => { origin: 'auto.ui.svelte', }); - expect(testInitSpan.finish).toHaveBeenCalledTimes(1); - expect(testUpdateSpan.finish).toHaveBeenCalledTimes(1); + expect(testInitSpan.end).toHaveBeenCalledTimes(1); + expect(testUpdateSpan.end).toHaveBeenCalledTimes(1); expect(testTransaction.spans.length).toEqual(2); }); it('creates an update span, when the component is updated', async () => { - // Make the finish() function actually end the initSpan - testInitSpan.finish.mockImplementation(() => { + // Make the end() function actually end the initSpan + testInitSpan.end.mockImplementation(() => { testInitSpan.endTimestamp = Date.now(); }); @@ -107,7 +107,7 @@ describe('Sentry.trackComponent()', () => { expect(testInitSpan.startChild).not.toHaveBeenCalled(); - expect(testInitSpan.finish).toHaveBeenCalledTimes(1); + expect(testInitSpan.end).toHaveBeenCalledTimes(1); expect(testTransaction.spans.length).toEqual(1); }); @@ -122,7 +122,7 @@ describe('Sentry.trackComponent()', () => { expect(testInitSpan.startChild).not.toHaveBeenCalled(); - expect(testInitSpan.finish).toHaveBeenCalledTimes(1); + expect(testInitSpan.end).toHaveBeenCalledTimes(1); expect(testTransaction.spans.length).toEqual(1); }); @@ -151,8 +151,8 @@ describe('Sentry.trackComponent()', () => { origin: 'auto.ui.svelte', }); - expect(testInitSpan.finish).toHaveBeenCalledTimes(1); - expect(testUpdateSpan.finish).toHaveBeenCalledTimes(1); + expect(testInitSpan.end).toHaveBeenCalledTimes(1); + expect(testUpdateSpan.end).toHaveBeenCalledTimes(1); expect(testTransaction.spans.length).toEqual(2); }); @@ -163,14 +163,14 @@ describe('Sentry.trackComponent()', () => { props: { options: { componentName: 'CustomComponentName' } }, }); - expect(testInitSpan.finish).toHaveBeenCalledTimes(0); - expect(testUpdateSpan.finish).toHaveBeenCalledTimes(0); + expect(testInitSpan.end).toHaveBeenCalledTimes(0); + expect(testUpdateSpan.end).toHaveBeenCalledTimes(0); expect(testTransaction.spans.length).toEqual(0); }); it("doesn't record update spans, if there's no ongoing transaction at that time", async () => { - // Make the finish() function actually end the initSpan - testInitSpan.finish.mockImplementation(() => { + // Make the end() function actually end the initSpan + testInitSpan.end.mockImplementation(() => { testInitSpan.endTimestamp = Date.now(); }); diff --git a/packages/sveltekit/src/client/router.ts b/packages/sveltekit/src/client/router.ts index 1883e5587c08..ede1ace4ae75 100644 --- a/packages/sveltekit/src/client/router.ts +++ b/packages/sveltekit/src/client/router.ts @@ -74,7 +74,7 @@ function instrumentNavigations(startTransactionFn: (context: TransactionContext) // So in this case, we can finish the routing span. If the transaction was an IdleTransaction, // it will finish automatically and if it was user-created users also need to finish it. if (routingSpan) { - routingSpan.finish(); + routingSpan.end(); routingSpan = undefined; } return; @@ -114,7 +114,7 @@ function instrumentNavigations(startTransactionFn: (context: TransactionContext) if (activeTransaction) { if (routingSpan) { // If a routing span is still open from a previous navigation, we finish it. - routingSpan.finish(); + routingSpan.end(); } routingSpan = activeTransaction.startChild({ op: 'ui.sveltekit.routing', diff --git a/packages/sveltekit/test/client/router.test.ts b/packages/sveltekit/test/client/router.test.ts index 37ebebd8d837..10e8a0aa0744 100644 --- a/packages/sveltekit/test/client/router.test.ts +++ b/packages/sveltekit/test/client/router.test.ts @@ -36,10 +36,10 @@ describe('sveltekitRoutingInstrumentation', () => { }); const mockedRoutingSpan = { - finish: () => {}, + end: () => {}, }; - const routingSpanFinishSpy = vi.spyOn(mockedRoutingSpan, 'finish'); + const routingSpanFinishSpy = vi.spyOn(mockedRoutingSpan, 'end'); beforeEach(() => { navigatingStore = writable(); diff --git a/packages/tracing-internal/src/browser/backgroundtab.ts b/packages/tracing-internal/src/browser/backgroundtab.ts index 7d65941c8d43..e13b997b16db 100644 --- a/packages/tracing-internal/src/browser/backgroundtab.ts +++ b/packages/tracing-internal/src/browser/backgroundtab.ts @@ -26,7 +26,7 @@ export function registerBackgroundTabDetection(): void { activeTransaction.setStatus(statusType); } activeTransaction.setTag('visibilitychange', 'document.hidden'); - activeTransaction.finish(); + activeTransaction.end(); } }); } else { diff --git a/packages/tracing-internal/src/browser/browsertracing.ts b/packages/tracing-internal/src/browser/browsertracing.ts index 93dc8716d71f..3b99dd9603d6 100644 --- a/packages/tracing-internal/src/browser/browsertracing.ts +++ b/packages/tracing-internal/src/browser/browsertracing.ts @@ -394,7 +394,7 @@ export class BrowserTracing implements Integration { if (inflightInteractionTransaction) { inflightInteractionTransaction.setFinishReason('interactionInterrupted'); - inflightInteractionTransaction.finish(); + inflightInteractionTransaction.end(); inflightInteractionTransaction = undefined; } diff --git a/packages/tracing-internal/src/browser/request.ts b/packages/tracing-internal/src/browser/request.ts index ab2f73b127f0..cc77ca4889f9 100644 --- a/packages/tracing-internal/src/browser/request.ts +++ b/packages/tracing-internal/src/browser/request.ts @@ -256,7 +256,7 @@ export function xhrCallback( const span = spans[spanId]; if (span && sentryXhrData.status_code !== undefined) { span.setHttpStatus(sentryXhrData.status_code); - span.finish(); + span.end(); // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete spans[spanId]; diff --git a/packages/tracing-internal/src/browser/router.ts b/packages/tracing-internal/src/browser/router.ts index 472c2e9fec05..27ad22ad90cc 100644 --- a/packages/tracing-internal/src/browser/router.ts +++ b/packages/tracing-internal/src/browser/router.ts @@ -52,7 +52,7 @@ export function instrumentRoutingWithDefaults( if (activeTransaction) { DEBUG_BUILD && logger.log(`[Tracing] Finishing current transaction with op: ${activeTransaction.op}`); // If there's an open transaction on the scope, we need to finish it before creating an new one. - activeTransaction.finish(); + activeTransaction.end(); } activeTransaction = customStartTransaction({ name: WINDOW.location.pathname, diff --git a/packages/tracing-internal/src/common/fetch.ts b/packages/tracing-internal/src/common/fetch.ts index 63f7f8ede721..2150518ea570 100644 --- a/packages/tracing-internal/src/common/fetch.ts +++ b/packages/tracing-internal/src/common/fetch.ts @@ -57,7 +57,7 @@ export function instrumentFetchRequest( } else if (handlerData.error) { span.setStatus('internal_error'); } - span.finish(); + span.end(); // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete spans[spanId]; diff --git a/packages/tracing-internal/src/node/integrations/apollo.ts b/packages/tracing-internal/src/node/integrations/apollo.ts index 033e0648d624..f46de137680a 100644 --- a/packages/tracing-internal/src/node/integrations/apollo.ts +++ b/packages/tracing-internal/src/node/integrations/apollo.ts @@ -200,12 +200,12 @@ function wrapResolver( if (isThenable(rv)) { return rv.then((res: unknown) => { - span?.finish(); + span?.end(); return res; }); } - span?.finish(); + span?.end(); return rv; }; diff --git a/packages/tracing-internal/src/node/integrations/express.ts b/packages/tracing-internal/src/node/integrations/express.ts index 0cbbf5d6af07..ab6451f1ec1c 100644 --- a/packages/tracing-internal/src/node/integrations/express.ts +++ b/packages/tracing-internal/src/node/integrations/express.ts @@ -163,7 +163,7 @@ function wrap(fn: Function, method: Method): (...args: any[]) => void { origin: 'auto.middleware.express', }); res.once('finish', () => { - span.finish(); + span.end(); }); } return fn.call(this, req, res); @@ -183,7 +183,7 @@ function wrap(fn: Function, method: Method): (...args: any[]) => void { origin: 'auto.middleware.express', }); fn.call(this, req, res, function (this: NodeJS.Global, ...args: unknown[]): void { - span?.finish(); + span?.end(); next.call(this, ...args); }); }; @@ -203,7 +203,7 @@ function wrap(fn: Function, method: Method): (...args: any[]) => void { origin: 'auto.middleware.express', }); fn.call(this, err, req, res, function (this: NodeJS.Global, ...args: unknown[]): void { - span?.finish(); + span?.end(); next.call(this, ...args); }); }; diff --git a/packages/tracing-internal/src/node/integrations/graphql.ts b/packages/tracing-internal/src/node/integrations/graphql.ts index 1fafae134ad7..16773daf49b6 100644 --- a/packages/tracing-internal/src/node/integrations/graphql.ts +++ b/packages/tracing-internal/src/node/integrations/graphql.ts @@ -66,14 +66,14 @@ export class GraphQL implements LazyLoadedIntegration { if (isThenable(rv)) { return rv.then((res: unknown) => { - span?.finish(); + span?.end(); scope?.setSpan(parentSpan); return res; }); } - span?.finish(); + span?.end(); scope?.setSpan(parentSpan); return rv; }; diff --git a/packages/tracing-internal/src/node/integrations/mongo.ts b/packages/tracing-internal/src/node/integrations/mongo.ts index fe6bc971d72e..966231db2f74 100644 --- a/packages/tracing-internal/src/node/integrations/mongo.ts +++ b/packages/tracing-internal/src/node/integrations/mongo.ts @@ -185,7 +185,7 @@ export class Mongo implements LazyLoadedIntegration { if (isThenable(maybePromiseOrCursor)) { return maybePromiseOrCursor.then((res: unknown) => { - span?.finish(); + span?.end(); return res; }); } @@ -196,17 +196,17 @@ export class Mongo implements LazyLoadedIntegration { try { cursor.once('close', () => { - span?.finish(); + span?.end(); }); } catch (e) { // If the cursor is already closed, `once` will throw an error. In that case, we can // finish the span immediately. - span?.finish(); + span?.end(); } return cursor; } else { - span?.finish(); + span?.end(); return maybePromiseOrCursor; } } @@ -214,7 +214,7 @@ export class Mongo implements LazyLoadedIntegration { const span = parentSpan?.startChild(getSpanContext(this, operation, args.slice(0, -1))); return orig.call(this, ...args.slice(0, -1), function (err: Error, result: unknown) { - span?.finish(); + span?.end(); lastArg(err, result); }); }; diff --git a/packages/tracing-internal/src/node/integrations/mysql.ts b/packages/tracing-internal/src/node/integrations/mysql.ts index 18038982c03d..c85b0021d89a 100644 --- a/packages/tracing-internal/src/node/integrations/mysql.ts +++ b/packages/tracing-internal/src/node/integrations/mysql.ts @@ -94,7 +94,7 @@ export class Mysql implements LazyLoadedIntegration { span.setData(key, data[key]); }); - span.finish(); + span.end(); } // The original function will have one of these signatures: diff --git a/packages/tracing-internal/src/node/integrations/postgres.ts b/packages/tracing-internal/src/node/integrations/postgres.ts index 918f20664b92..810f07825653 100644 --- a/packages/tracing-internal/src/node/integrations/postgres.ts +++ b/packages/tracing-internal/src/node/integrations/postgres.ts @@ -137,14 +137,14 @@ export class Postgres implements LazyLoadedIntegration { if (typeof callback === 'function') { return orig.call(this, config, values, function (err: Error, result: unknown) { - span?.finish(); + span?.end(); callback(err, result); }); } if (typeof values === 'function') { return orig.call(this, config, function (err: Error, result: unknown) { - span?.finish(); + span?.end(); values(err, result); }); } @@ -153,12 +153,12 @@ export class Postgres implements LazyLoadedIntegration { if (isThenable(rv)) { return rv.then((res: unknown) => { - span?.finish(); + span?.end(); return res; }); } - span?.finish(); + span?.end(); return rv; }; }); diff --git a/packages/tracing-internal/test/browser/browsertracing.test.ts b/packages/tracing-internal/test/browser/browsertracing.test.ts index 65de2adbd85d..3cbd6eb9f6b4 100644 --- a/packages/tracing-internal/test/browser/browsertracing.test.ts +++ b/packages/tracing-internal/test/browser/browsertracing.test.ts @@ -70,7 +70,7 @@ conditionalTest({ min: 10 })('BrowserTracing', () => { const activeTransaction = getActiveTransaction(); if (activeTransaction) { // Should unset off of scope. - activeTransaction.finish(); + activeTransaction.end(); } }); @@ -178,10 +178,10 @@ conditionalTest({ min: 10 })('BrowserTracing', () => { const transaction = getActiveTransaction(hub) as IdleTransaction; const span = transaction.startChild(); - span.finish(); + span.end(); if (span.endTimestamp) { - transaction.finish(span.endTimestamp + 12345); + transaction.end(span.endTimestamp + 12345); } expect(transaction.endTimestamp).toBe(span.endTimestamp); }); @@ -418,10 +418,10 @@ conditionalTest({ min: 10 })('BrowserTracing', () => { createBrowserTracing(true, { routingInstrumentation: customInstrumentRouting }); const mockFinish = jest.fn(); const transaction = getActiveTransaction(hub) as IdleTransaction; - transaction.finish = mockFinish; + transaction.end = mockFinish; const span = transaction.startChild(); // activities = 1 - span.finish(); // activities = 0 + span.end(); // activities = 0 expect(mockFinish).toHaveBeenCalledTimes(0); jest.advanceTimersByTime(TRACING_DEFAULTS.idleTimeout); @@ -432,10 +432,10 @@ conditionalTest({ min: 10 })('BrowserTracing', () => { createBrowserTracing(true, { idleTimeout: 2000, routingInstrumentation: customInstrumentRouting }); const mockFinish = jest.fn(); const transaction = getActiveTransaction(hub) as IdleTransaction; - transaction.finish = mockFinish; + transaction.end = mockFinish; const span = transaction.startChild(); // activities = 1 - span.finish(); // activities = 0 + span.end(); // activities = 0 expect(mockFinish).toHaveBeenCalledTimes(0); jest.advanceTimersByTime(2000); @@ -447,7 +447,7 @@ conditionalTest({ min: 10 })('BrowserTracing', () => { const transaction = getActiveTransaction(hub) as IdleTransaction; const span = transaction.startChild(); // activities = 1 - span.finish(); // activities = 0 + span.end(); // activities = 0 jest.advanceTimersByTime(TRACING_DEFAULTS.idleTimeout); expect(mockStartTrackingWebVitals).toHaveBeenCalledTimes(1); @@ -460,10 +460,10 @@ conditionalTest({ min: 10 })('BrowserTracing', () => { createBrowserTracing(true, { heartbeatInterval: interval, routingInstrumentation: customInstrumentRouting }); const mockFinish = jest.fn(); const transaction = getActiveTransaction(hub) as IdleTransaction; - transaction.finish = mockFinish; + transaction.end = mockFinish; const span = transaction.startChild(); // activities = 1 - span.finish(); // activities = 0 + span.end(); // activities = 0 expect(mockFinish).toHaveBeenCalledTimes(0); jest.advanceTimersByTime(interval * 3); diff --git a/packages/tracing-internal/test/browser/router.test.ts b/packages/tracing-internal/test/browser/router.test.ts index a78d9e5631bd..a27926ad9803 100644 --- a/packages/tracing-internal/test/browser/router.test.ts +++ b/packages/tracing-internal/test/browser/router.test.ts @@ -17,7 +17,7 @@ jest.mock('@sentry/utils', () => { conditionalTest({ min: 16 })('instrumentRoutingWithDefaults', () => { const mockFinish = jest.fn(); - const customStartTransaction = jest.fn().mockReturnValue({ finish: mockFinish }); + const customStartTransaction = jest.fn().mockReturnValue({ end: mockFinish }); beforeEach(() => { const dom = new JSDOM(); // @ts-expect-error need to override global document diff --git a/packages/tracing/test/hub.test.ts b/packages/tracing/test/hub.test.ts index 817e88c9c55e..f7cf93cc5e32 100644 --- a/packages/tracing/test/hub.test.ts +++ b/packages/tracing/test/hub.test.ts @@ -415,11 +415,11 @@ describe('Hub', () => { makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); - jest.spyOn(transaction, 'finish'); - transaction.finish(); + jest.spyOn(transaction, 'end'); + transaction.end(); expect(transaction.sampled).toBe(false); - expect(transaction.finish).toReturnWith(undefined); + expect(transaction.end).toReturnWith(undefined); expect(client.captureEvent).not.toBeCalled(); }); @@ -432,11 +432,11 @@ describe('Hub', () => { makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); - jest.spyOn(transaction, 'finish'); - transaction.finish(); + jest.spyOn(transaction, 'end'); + transaction.end(); expect(transaction.sampled).toBe(false); - expect(transaction.finish).toReturnWith(undefined); + expect(transaction.end).toReturnWith(undefined); expect(client.captureEvent).not.toBeCalled(); expect(logger.error).toHaveBeenCalledWith( `A transaction was started with instrumenter=\`sentry\`, but the SDK is configured with the \`otel\` instrumenter. @@ -633,7 +633,7 @@ The transaction will not be sampled. Please use the otel instrumentation to star transaction.startChild({ op: 'test', startTimestamp: 1200, endTimestamp: 1500 }); - transaction.finish(2000); + transaction.end(2000); expect(captureEventSpy).toHaveBeenCalledTimes(1); expect(captureEventSpy.mock.calls[0][0].timestamp).toEqual(1500); diff --git a/packages/tracing/test/idletransaction.test.ts b/packages/tracing/test/idletransaction.test.ts index 30cd97f775b1..e0c5dd189cff 100644 --- a/packages/tracing/test/idletransaction.test.ts +++ b/packages/tracing/test/idletransaction.test.ts @@ -48,7 +48,7 @@ describe('IdleTransaction', () => { ); transaction.initSpanRecorder(10); - transaction.finish(); + transaction.end(); jest.runAllTimers(); const scope = hub.getScope(); @@ -65,7 +65,7 @@ describe('IdleTransaction', () => { true, ); - transaction.finish(); + transaction.end(); jest.runAllTimers(); const scope = hub.getScope(); @@ -87,7 +87,7 @@ describe('IdleTransaction', () => { const otherTransaction = new Transaction({ name: 'bar' }, hub); hub.getScope().setSpan(otherTransaction); - transaction.finish(); + transaction.end(); jest.runAllTimers(); const scope = hub.getScope(); @@ -101,7 +101,7 @@ describe('IdleTransaction', () => { it('push and pops activities', () => { const transaction = new IdleTransaction({ name: 'foo' }, hub); - const mockFinish = jest.spyOn(transaction, 'finish'); + const mockFinish = jest.spyOn(transaction, 'end'); transaction.initSpanRecorder(10); expect(transaction.activities).toMatchObject({}); @@ -110,7 +110,7 @@ describe('IdleTransaction', () => { expect(mockFinish).toHaveBeenCalledTimes(0); - span.finish(); + span.end(); expect(transaction.activities).toMatchObject({}); jest.runOnlyPendingTimers(); @@ -128,7 +128,7 @@ describe('IdleTransaction', () => { it('does not finish if there are still active activities', () => { const transaction = new IdleTransaction({ name: 'foo' }, hub); - const mockFinish = jest.spyOn(transaction, 'finish'); + const mockFinish = jest.spyOn(transaction, 'end'); transaction.initSpanRecorder(10); expect(transaction.activities).toMatchObject({}); @@ -136,7 +136,7 @@ describe('IdleTransaction', () => { const childSpan = span.startChild(); expect(transaction.activities).toMatchObject({ [span.spanId]: true, [childSpan.spanId]: true }); - span.finish(); + span.end(); jest.advanceTimersByTime(TRACING_DEFAULTS.idleTimeout + 1); expect(mockFinish).toHaveBeenCalledTimes(0); @@ -155,7 +155,7 @@ describe('IdleTransaction', () => { expect(mockCallback2).toHaveBeenCalledTimes(0); const span = transaction.startChild(); - span.finish(); + span.end(); jest.runOnlyPendingTimers(); expect(mockCallback1).toHaveBeenCalledTimes(1); @@ -177,8 +177,8 @@ describe('IdleTransaction', () => { // Should be cancelled - will not finish const cancelledSpan = transaction.startChild({ startTimestamp: transaction.startTimestamp + 4 }); - regularSpan.finish(regularSpan.startTimestamp + 4); - transaction.finish(transaction.startTimestamp + 10); + regularSpan.end(regularSpan.startTimestamp + 4); + transaction.end(transaction.startTimestamp + 10); expect(transaction.spanRecorder).toBeDefined(); if (transaction.spanRecorder) { @@ -202,9 +202,9 @@ describe('IdleTransaction', () => { transaction.initSpanRecorder(10); const span = transaction.startChild({ startTimestamp: transaction.startTimestamp + 2 }); - span.finish(span.startTimestamp + 10 + 30 + 1); + span.end(span.startTimestamp + 10 + 30 + 1); - transaction.finish(transaction.startTimestamp + 50); + transaction.end(transaction.startTimestamp + 50); expect(transaction.spanRecorder).toBeDefined(); expect(transaction.spanRecorder!.spans).toHaveLength(1); @@ -218,7 +218,7 @@ describe('IdleTransaction', () => { const recordDroppedEventSpy = jest.spyOn(client, 'recordDroppedEvent'); transaction.initSpanRecorder(10); - transaction.finish(transaction.startTimestamp + 10); + transaction.end(transaction.startTimestamp + 10); expect(recordDroppedEventSpy).toHaveBeenCalledWith('sample_rate', 'transaction'); }); @@ -247,12 +247,12 @@ describe('IdleTransaction', () => { transaction.initSpanRecorder(10); const span = transaction.startChild({}); - span.finish(); + span.end(); jest.advanceTimersByTime(2); const span2 = transaction.startChild({}); - span2.finish(); + span2.end(); jest.advanceTimersByTime(8); @@ -265,12 +265,12 @@ describe('IdleTransaction', () => { transaction.initSpanRecorder(10); const span = transaction.startChild({}); - span.finish(); + span.end(); jest.advanceTimersByTime(2); const span2 = transaction.startChild({}); - span2.finish(); + span2.end(); jest.advanceTimersByTime(10); @@ -287,8 +287,8 @@ describe('IdleTransaction', () => { const firstSpan = transaction.startChild({}); transaction.cancelIdleTimeout(undefined, { restartOnChildSpanChange: false }); const secondSpan = transaction.startChild({}); - firstSpan.finish(); - secondSpan.finish(); + firstSpan.end(); + secondSpan.end(); expect(transaction.endTimestamp).toBeDefined(); }); @@ -303,13 +303,13 @@ describe('IdleTransaction', () => { const secondSpan = transaction.startChild({}); const thirdSpan = transaction.startChild({}); - firstSpan.finish(); + firstSpan.end(); expect(transaction.endTimestamp).toBeUndefined(); - secondSpan.finish(); + secondSpan.end(); expect(transaction.endTimestamp).toBeUndefined(); - thirdSpan.finish(); + thirdSpan.end(); expect(transaction.endTimestamp).toBeDefined(); }); @@ -319,7 +319,7 @@ describe('IdleTransaction', () => { transaction.initSpanRecorder(10); const span = transaction.startChild({}); - span.finish(); + span.end(); jest.advanceTimersByTime(2); @@ -334,14 +334,14 @@ describe('IdleTransaction', () => { transaction.initSpanRecorder(10); const span = transaction.startChild({}); - span.finish(); + span.end(); jest.advanceTimersByTime(2); transaction.cancelIdleTimeout(); const span2 = transaction.startChild({}); - span2.finish(); + span2.end(); jest.advanceTimersByTime(8); expect(transaction.endTimestamp).toBeUndefined(); @@ -355,7 +355,7 @@ describe('IdleTransaction', () => { it('does not mark transaction as `DeadlineExceeded` if idle timeout has not been reached', () => { // 20s to exceed 3 heartbeats const transaction = new IdleTransaction({ name: 'foo' }, hub, 20000); - const mockFinish = jest.spyOn(transaction, 'finish'); + const mockFinish = jest.spyOn(transaction, 'end'); expect(transaction.status).not.toEqual('deadline_exceeded'); expect(mockFinish).toHaveBeenCalledTimes(0); @@ -378,7 +378,7 @@ describe('IdleTransaction', () => { it('finishes a transaction after 3 beats', () => { const transaction = new IdleTransaction({ name: 'foo' }, hub, TRACING_DEFAULTS.idleTimeout); - const mockFinish = jest.spyOn(transaction, 'finish'); + const mockFinish = jest.spyOn(transaction, 'end'); transaction.initSpanRecorder(10); expect(mockFinish).toHaveBeenCalledTimes(0); @@ -399,7 +399,7 @@ describe('IdleTransaction', () => { it('resets after new activities are added', () => { const transaction = new IdleTransaction({ name: 'foo' }, hub, TRACING_DEFAULTS.idleTimeout, 50000); - const mockFinish = jest.spyOn(transaction, 'finish'); + const mockFinish = jest.spyOn(transaction, 'end'); transaction.initSpanRecorder(10); expect(mockFinish).toHaveBeenCalledTimes(0); @@ -430,7 +430,7 @@ describe('IdleTransaction', () => { jest.advanceTimersByTime(TRACING_DEFAULTS.heartbeatInterval); expect(mockFinish).toHaveBeenCalledTimes(0); - span.finish(); // pop activity + span.end(); // pop activity // Beat 1 jest.advanceTimersByTime(TRACING_DEFAULTS.heartbeatInterval); @@ -469,7 +469,7 @@ describe('IdleTransactionSpanRecorder', () => { expect(mockPushActivity).toHaveBeenLastCalledWith(span.spanId); expect(mockPopActivity).toHaveBeenCalledTimes(0); - span.finish(); + span.end(); expect(mockPushActivity).toHaveBeenCalledTimes(1); expect(mockPopActivity).toHaveBeenCalledTimes(1); expect(mockPushActivity).toHaveBeenLastCalledWith(span.spanId); diff --git a/packages/tracing/test/integrations/apollo-nestjs.test.ts b/packages/tracing/test/integrations/apollo-nestjs.test.ts index 703edcaad23d..7e9866146385 100644 --- a/packages/tracing/test/integrations/apollo-nestjs.test.ts +++ b/packages/tracing/test/integrations/apollo-nestjs.test.ts @@ -84,7 +84,7 @@ describe('setupOnce', () => { jest.spyOn(scope, 'getSpan').mockReturnValueOnce(parentSpan); jest.spyOn(scope, 'setSpan'); jest.spyOn(parentSpan, 'startChild').mockReturnValueOnce(childSpan); - jest.spyOn(childSpan, 'finish'); + jest.spyOn(childSpan, 'end'); }); it('should wrap a simple resolver', () => { @@ -95,7 +95,7 @@ describe('setupOnce', () => { op: 'graphql.resolve', origin: 'auto.graphql.apollo', }); - expect(childSpan.finish).toBeCalled(); + expect(childSpan.end).toBeCalled(); }); it('should wrap another simple resolver', () => { @@ -106,7 +106,7 @@ describe('setupOnce', () => { op: 'graphql.resolve', origin: 'auto.graphql.apollo', }); - expect(childSpan.finish).toBeCalled(); + expect(childSpan.end).toBeCalled(); }); it("doesn't attach when using otel instrumenter", () => { diff --git a/packages/tracing/test/integrations/apollo.test.ts b/packages/tracing/test/integrations/apollo.test.ts index 90da1f8e0b21..ea861dcdec1f 100644 --- a/packages/tracing/test/integrations/apollo.test.ts +++ b/packages/tracing/test/integrations/apollo.test.ts @@ -84,7 +84,7 @@ describe('setupOnce', () => { jest.spyOn(scope, 'getSpan').mockReturnValueOnce(parentSpan); jest.spyOn(scope, 'setSpan'); jest.spyOn(parentSpan, 'startChild').mockReturnValueOnce(childSpan); - jest.spyOn(childSpan, 'finish'); + jest.spyOn(childSpan, 'end'); }); it('should wrap a simple resolver', () => { @@ -95,7 +95,7 @@ describe('setupOnce', () => { op: 'graphql.resolve', origin: 'auto.graphql.apollo', }); - expect(childSpan.finish).toBeCalled(); + expect(childSpan.end).toBeCalled(); }); it('should wrap another simple resolver', () => { @@ -106,7 +106,7 @@ describe('setupOnce', () => { op: 'graphql.resolve', origin: 'auto.graphql.apollo', }); - expect(childSpan.finish).toBeCalled(); + expect(childSpan.end).toBeCalled(); }); it("doesn't attach when using otel instrumenter", () => { diff --git a/packages/tracing/test/integrations/graphql.test.ts b/packages/tracing/test/integrations/graphql.test.ts index c61f287c3e86..06b9495d8061 100644 --- a/packages/tracing/test/integrations/graphql.test.ts +++ b/packages/tracing/test/integrations/graphql.test.ts @@ -46,7 +46,7 @@ describe('setupOnce', () => { jest.spyOn(scope, 'getSpan').mockReturnValueOnce(parentSpan); jest.spyOn(scope, 'setSpan'); jest.spyOn(parentSpan, 'startChild').mockReturnValueOnce(childSpan); - jest.spyOn(childSpan, 'finish'); + jest.spyOn(childSpan, 'end'); }); it('should wrap execute method', async () => { @@ -57,7 +57,7 @@ describe('setupOnce', () => { op: 'graphql.execute', origin: 'auto.graphql.graphql', }); - expect(childSpan.finish).toBeCalled(); + expect(childSpan.end).toBeCalled(); expect(scope.setSpan).toHaveBeenCalledTimes(2); }); diff --git a/packages/tracing/test/integrations/node/mongo.test.ts b/packages/tracing/test/integrations/node/mongo.test.ts index 30e5c76563bd..e2ab62ab2e04 100644 --- a/packages/tracing/test/integrations/node/mongo.test.ts +++ b/packages/tracing/test/integrations/node/mongo.test.ts @@ -66,7 +66,7 @@ describe('patchOperation()', () => { childSpan = parentSpan.startChild(); jest.spyOn(scope, 'getSpan').mockReturnValueOnce(parentSpan); jest.spyOn(parentSpan, 'startChild').mockReturnValueOnce(childSpan); - jest.spyOn(childSpan, 'finish'); + jest.spyOn(childSpan, 'end'); }); it('should wrap method accepting callback as the last argument', done => { @@ -84,7 +84,7 @@ describe('patchOperation()', () => { origin: 'auto.db.mongo', description: 'insertOne', }); - expect(childSpan.finish).toBeCalled(); + expect(childSpan.end).toBeCalled(); done(); }) as void; }); @@ -104,7 +104,7 @@ describe('patchOperation()', () => { origin: 'auto.db.mongo', description: 'insertOne', }); - expect(childSpan.finish).toBeCalled(); + expect(childSpan.end).toBeCalled(); }); it('should wrap method accepting no callback as the last argument and not returning promise', () => { @@ -121,7 +121,7 @@ describe('patchOperation()', () => { origin: 'auto.db.mongo', description: 'initializeOrderedBulkOp', }); - expect(childSpan.finish).toBeCalled(); + expect(childSpan.end).toBeCalled(); }); it("doesn't attach when using otel instrumenter", () => { diff --git a/packages/tracing/test/integrations/node/postgres.test.ts b/packages/tracing/test/integrations/node/postgres.test.ts index 446d837d22d7..c94b9870907b 100644 --- a/packages/tracing/test/integrations/node/postgres.test.ts +++ b/packages/tracing/test/integrations/node/postgres.test.ts @@ -67,7 +67,7 @@ describe('setupOnce', () => { childSpan = parentSpan.startChild(); jest.spyOn(scope, 'getSpan').mockReturnValueOnce(parentSpan); jest.spyOn(parentSpan, 'startChild').mockReturnValueOnce(childSpan); - jest.spyOn(childSpan, 'finish'); + jest.spyOn(childSpan, 'end'); }); it(`should wrap ${pgApi}'s query method accepting callback as the last argument`, done => { @@ -81,7 +81,7 @@ describe('setupOnce', () => { 'db.system': 'postgresql', }, }); - expect(childSpan.finish).toBeCalled(); + expect(childSpan.end).toBeCalled(); done(); }) as void; }); @@ -97,7 +97,7 @@ describe('setupOnce', () => { 'db.system': 'postgresql', }, }); - expect(childSpan.finish).toBeCalled(); + expect(childSpan.end).toBeCalled(); done(); }) as void; }); @@ -113,7 +113,7 @@ describe('setupOnce', () => { 'db.system': 'postgresql', }, }); - expect(childSpan.finish).toBeCalled(); + expect(childSpan.end).toBeCalled(); }); }); diff --git a/packages/tracing/test/span.test.ts b/packages/tracing/test/span.test.ts index 3e6c267b1233..c5a3c602952e 100644 --- a/packages/tracing/test/span.test.ts +++ b/packages/tracing/test/span.test.ts @@ -56,7 +56,7 @@ describe('Span', () => { const transaction = new Transaction({ name: 'test', sampled: true }); const span2 = transaction.startChild(); const span3 = span2.startChild(); - span3.finish(); + span3.end(); expect(transaction.spanRecorder).toBe(span2.spanRecorder); expect(transaction.spanRecorder).toBe(span3.spanRecorder); }); @@ -173,7 +173,7 @@ describe('Span', () => { test('simple', () => { const span = new Span({}); expect(span.endTimestamp).toBeUndefined(); - span.finish(); + span.end(); expect(span.endTimestamp).toBeGreaterThan(1); }); @@ -181,7 +181,7 @@ describe('Span', () => { test('finish a transaction', () => { const spy = jest.spyOn(hub as any, 'captureEvent') as any; const transaction = hub.startTransaction({ name: 'test' }); - transaction.finish(); + transaction.end(); expect(spy).toHaveBeenCalled(); expect(spy.mock.calls[0][0].spans).toHaveLength(0); expect(spy.mock.calls[0][0].timestamp).toBeTruthy(); @@ -193,8 +193,8 @@ describe('Span', () => { const spy = jest.spyOn(hub as any, 'captureEvent') as any; const transaction = hub.startTransaction({ name: 'test' }); const childSpan = transaction.startChild(); - childSpan.finish(); - transaction.finish(); + childSpan.end(); + transaction.end(); expect(spy).toHaveBeenCalled(); expect(spy.mock.calls[0][0].spans).toHaveLength(1); expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); @@ -205,8 +205,8 @@ describe('Span', () => { const spy = jest.spyOn(hub as any, 'captureEvent') as any; const transaction = hub.startTransaction({ name: 'test', op: 'parent', sampled: true }); const childSpan = transaction.startChild({ op: 'child' }); - childSpan.finish(); - transaction.finish(); + childSpan.end(); + transaction.end(); expect(spy).toHaveBeenCalled(); expect(spy.mock.calls[0][0].spans).toHaveLength(1); expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); @@ -216,7 +216,7 @@ describe('Span', () => { const spy = jest.spyOn(hub as any, 'captureEvent') as any; const transaction = hub.startTransaction({ name: 'test' }); const childSpan = transaction.startChild(); - childSpan.finish(); + childSpan.end(); expect(spy).not.toHaveBeenCalled(); }); @@ -224,13 +224,13 @@ describe('Span', () => { const spy = jest.spyOn(hub as any, 'captureEvent') as any; const transaction = hub.startTransaction({ name: 'test' }); const childSpanOne = transaction.startChild(); - childSpanOne.finish(); + childSpanOne.end(); hub.getScope().setSpan(childSpanOne); const spanTwo = transaction.startChild(); - spanTwo.finish(); - transaction.finish(); + spanTwo.end(); + transaction.end(); expect(spy).toHaveBeenCalled(); expect(spy.mock.calls[0][0].spans).toHaveLength(2); @@ -247,9 +247,9 @@ describe('Span', () => { const transaction = _hub.startTransaction({ name: 'test' }); for (let i = 0; i < 10; i++) { const child = transaction.startChild(); - child.finish(); + child.end(); } - transaction.finish(); + transaction.end(); expect(spy.mock.calls[0][0].spans).toHaveLength(3); }); @@ -262,9 +262,9 @@ describe('Span', () => { const transaction = _hub.startTransaction({ name: 'test', sampled: false }); for (let i = 0; i < 10; i++) { const child = transaction.startChild(); - child.finish(); + child.end(); } - transaction.finish(); + transaction.end(); expect((transaction as any).spanRecorder).toBeUndefined(); expect(spy).not.toHaveBeenCalled(); }); @@ -276,15 +276,158 @@ describe('Span', () => { const childSpanOne = transaction.startChild(); const childSpanTwo = childSpanOne.startChild(); - childSpanTwo.finish(); + childSpanTwo.end(); - childSpanOne.finish(); + childSpanOne.end(); hub.getScope().setSpan(transaction); const spanTwo = transaction.startChild({}); - spanTwo.finish(); - transaction.finish(); + spanTwo.end(); + transaction.end(); + + expect(spy).toHaveBeenCalled(); + expect(spy.mock.calls[0][0].spans).toHaveLength(3); + expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); + expect(childSpanOne.toJSON().parent_span_id).toEqual(transaction.toJSON().span_id); + expect(childSpanTwo.toJSON().parent_span_id).toEqual(childSpanOne.toJSON().span_id); + expect(spanTwo.toJSON().parent_span_id).toEqual(transaction.toJSON().span_id); + }); + }); + }); + + describe('end', () => { + test('simple', () => { + const span = new Span({}); + expect(span.endTimestamp).toBeUndefined(); + span.end(); + expect(span.endTimestamp).toBeGreaterThan(1); + }); + + test('with endTime in seconds', () => { + const span = new Span({}); + expect(span.endTimestamp).toBeUndefined(); + const endTime = Date.now() / 1000; + span.end(endTime); + expect(span.endTimestamp).toBe(endTime); + }); + + test('with endTime in milliseconds', () => { + const span = new Span({}); + expect(span.endTimestamp).toBeUndefined(); + const endTime = Date.now(); + span.end(endTime); + expect(span.endTimestamp).toBe(endTime / 1000); + }); + + describe('hub.startTransaction', () => { + test('finish a transaction', () => { + const spy = jest.spyOn(hub as any, 'captureEvent') as any; + const transaction = hub.startTransaction({ name: 'test' }); + transaction.end(); + expect(spy).toHaveBeenCalled(); + expect(spy.mock.calls[0][0].spans).toHaveLength(0); + expect(spy.mock.calls[0][0].timestamp).toBeTruthy(); + expect(spy.mock.calls[0][0].start_timestamp).toBeTruthy(); + expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); + }); + + test('finish a transaction + child span', () => { + const spy = jest.spyOn(hub as any, 'captureEvent') as any; + const transaction = hub.startTransaction({ name: 'test' }); + const childSpan = transaction.startChild(); + childSpan.end(); + transaction.end(); + expect(spy).toHaveBeenCalled(); + expect(spy.mock.calls[0][0].spans).toHaveLength(1); + expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); + }); + + // See https://github.com/getsentry/sentry-javascript/issues/3254 + test('finish a transaction + child span + sampled:true', () => { + const spy = jest.spyOn(hub as any, 'captureEvent') as any; + const transaction = hub.startTransaction({ name: 'test', op: 'parent', sampled: true }); + const childSpan = transaction.startChild({ op: 'child' }); + childSpan.end(); + transaction.end(); + expect(spy).toHaveBeenCalled(); + expect(spy.mock.calls[0][0].spans).toHaveLength(1); + expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); + }); + + test("finish a child span shouldn't trigger captureEvent", () => { + const spy = jest.spyOn(hub as any, 'captureEvent') as any; + const transaction = hub.startTransaction({ name: 'test' }); + const childSpan = transaction.startChild(); + childSpan.end(); + expect(spy).not.toHaveBeenCalled(); + }); + + test("finish a span with another one on the scope shouldn't override contexts.trace", () => { + const spy = jest.spyOn(hub as any, 'captureEvent') as any; + const transaction = hub.startTransaction({ name: 'test' }); + const childSpanOne = transaction.startChild(); + childSpanOne.end(); + + hub.getScope().setSpan(childSpanOne); + + const spanTwo = transaction.startChild(); + spanTwo.end(); + transaction.end(); + + expect(spy).toHaveBeenCalled(); + expect(spy.mock.calls[0][0].spans).toHaveLength(2); + expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); + }); + + test('maxSpans correctly limits number of spans', () => { + const options = getDefaultBrowserClientOptions({ + _experiments: { maxSpans: 3 }, + tracesSampleRate: 1, + }); + const _hub = new Hub(new BrowserClient(options)); + const spy = jest.spyOn(_hub as any, 'captureEvent') as any; + const transaction = _hub.startTransaction({ name: 'test' }); + for (let i = 0; i < 10; i++) { + const child = transaction.startChild(); + child.end(); + } + transaction.end(); + expect(spy.mock.calls[0][0].spans).toHaveLength(3); + }); + + test('no span recorder created if transaction.sampled is false', () => { + const options = getDefaultBrowserClientOptions({ + tracesSampleRate: 1, + }); + const _hub = new Hub(new BrowserClient(options)); + const spy = jest.spyOn(_hub as any, 'captureEvent') as any; + const transaction = _hub.startTransaction({ name: 'test', sampled: false }); + for (let i = 0; i < 10; i++) { + const child = transaction.startChild(); + child.end(); + } + transaction.end(); + expect((transaction as any).spanRecorder).toBeUndefined(); + expect(spy).not.toHaveBeenCalled(); + }); + + test('tree structure of spans should be correct when mixing it with span on scope', () => { + const spy = jest.spyOn(hub as any, 'captureEvent') as any; + + const transaction = hub.startTransaction({ name: 'test' }); + const childSpanOne = transaction.startChild(); + + const childSpanTwo = childSpanOne.startChild(); + childSpanTwo.end(); + + childSpanOne.end(); + + hub.getScope().setSpan(transaction); + + const spanTwo = transaction.startChild({}); + spanTwo.end(); + transaction.end(); expect(spy).toHaveBeenCalled(); expect(spy.mock.calls[0][0].spans).toHaveLength(3); @@ -508,7 +651,7 @@ describe('Span', () => { }); expect(spy).toHaveBeenCalledTimes(0); - transaction.finish(); + transaction.end(); expect(spy).toHaveBeenCalledTimes(1); expect(spy).toHaveBeenLastCalledWith( expect.objectContaining({ diff --git a/packages/tracing/test/transaction.test.ts b/packages/tracing/test/transaction.test.ts index 979dc119531e..64691385f533 100644 --- a/packages/tracing/test/transaction.test.ts +++ b/packages/tracing/test/transaction.test.ts @@ -141,7 +141,7 @@ describe('`Transaction` class', () => { const transaction = hub.startTransaction({ name: 'dogpark' }); transaction.setContext('foo', { key: 'val' }); - transaction.finish(); + transaction.end(); // eslint-disable-next-line @typescript-eslint/unbound-method expect(hub.captureEvent).toHaveBeenCalledTimes(1); @@ -169,7 +169,7 @@ describe('`Transaction` class', () => { const transaction = hub.startTransaction({ name: 'dogpark' }); transaction.setContext('trace', { key: 'val' }); - transaction.finish(); + transaction.end(); // eslint-disable-next-line @typescript-eslint/unbound-method expect(hub.captureEvent).toHaveBeenCalledTimes(1); diff --git a/packages/types/src/hub.ts b/packages/types/src/hub.ts index 8d4d47885d40..ca18e088340a 100644 --- a/packages/types/src/hub.ts +++ b/packages/types/src/hub.ts @@ -200,7 +200,7 @@ export interface Hub { * * Every child span must be finished before the transaction is finished, otherwise the unfinished spans are discarded. * - * The transaction must be finished with a call to its `.finish()` method, at which point the transaction with all its + * The transaction must be finished with a call to its `.end()` method, at which point the transaction with all its * finished child spans will be sent to Sentry. * * @param context Properties of the new `Transaction`. diff --git a/packages/types/src/span.ts b/packages/types/src/span.ts index c931b7e457c2..1877d7a25524 100644 --- a/packages/types/src/span.ts +++ b/packages/types/src/span.ts @@ -134,6 +134,11 @@ export interface Span extends SpanContext { */ finish(endTimestamp?: number): void; + /** + * End the current span. + */ + end(endTimestamp?: number): void; + /** * Sets the tag attribute on the current span. * diff --git a/packages/vue/src/tracing.ts b/packages/vue/src/tracing.ts index ef509dcdb406..810fa40b045d 100644 --- a/packages/vue/src/tracing.ts +++ b/packages/vue/src/tracing.ts @@ -45,7 +45,7 @@ function finishRootSpan(vm: VueSentry, timestamp: number, timeout: number): void vm.$_sentryRootSpanTimer = setTimeout(() => { if (vm.$root && vm.$root.$_sentryRootSpan) { - vm.$root.$_sentryRootSpan.finish(timestamp); + vm.$root.$_sentryRootSpan.end(timestamp); vm.$root.$_sentryRootSpan = undefined; } }, timeout); @@ -108,7 +108,7 @@ export const createTracingMixins = (options: TracingOptions): Mixins => { // finished so we finish the span before starting a new one, just to be sure. const oldSpan = this.$_sentrySpans[operation]; if (oldSpan && !oldSpan.endTimestamp) { - oldSpan.finish(); + oldSpan.end(); } this.$_sentrySpans[operation] = activeTransaction.startChild({ @@ -123,7 +123,7 @@ export const createTracingMixins = (options: TracingOptions): Mixins => { // The before hook did not start the tracking span, so the span was not added. // This is probably because it happened before there is an active transaction if (!span) return; - span.finish(); + span.end(); finishRootSpan(this, timestampInSeconds(), options.timeout); }