diff --git a/packages/browser/src/transports/fetch.ts b/packages/browser/src/transports/fetch.ts index 241f2a1e8bc5..46c652bdea3e 100644 --- a/packages/browser/src/transports/fetch.ts +++ b/packages/browser/src/transports/fetch.ts @@ -1,5 +1,5 @@ import { eventToSentryRequest, sessionToSentryRequest } from '@sentry/core'; -import { Event, Outcome, Response, SentryRequest, Session, TransportOptions } from '@sentry/types'; +import { Event, Response, SentryRequest, Session, TransportOptions } from '@sentry/types'; import { SentryError, supportsReferrerPolicy, SyncPromise } from '@sentry/utils'; import { BaseTransport } from './base'; @@ -37,7 +37,7 @@ export class FetchTransport extends BaseTransport { */ private _sendRequest(sentryRequest: SentryRequest, originalPayload: Event | Session): PromiseLike { if (this._isRateLimited(sentryRequest.type)) { - this.recordLostEvent(Outcome.RateLimitBackoff, sentryRequest.type); + this.recordLostEvent('ratelimit_backoff', sentryRequest.type); return Promise.reject({ event: originalPayload, @@ -89,9 +89,9 @@ export class FetchTransport extends BaseTransport { .then(undefined, reason => { // It's either buffer rejection or any other xhr/fetch error, which are treated as NetworkError. if (reason instanceof SentryError) { - this.recordLostEvent(Outcome.QueueOverflow, sentryRequest.type); + this.recordLostEvent('queue_overflow', sentryRequest.type); } else { - this.recordLostEvent(Outcome.NetworkError, sentryRequest.type); + this.recordLostEvent('network_error', sentryRequest.type); } throw reason; }); diff --git a/packages/browser/src/transports/xhr.ts b/packages/browser/src/transports/xhr.ts index 771cb16d2a51..1d5dd91f9c0b 100644 --- a/packages/browser/src/transports/xhr.ts +++ b/packages/browser/src/transports/xhr.ts @@ -1,5 +1,5 @@ import { eventToSentryRequest, sessionToSentryRequest } from '@sentry/core'; -import { Event, Outcome, Response, SentryRequest, Session } from '@sentry/types'; +import { Event, Response, SentryRequest, Session } from '@sentry/types'; import { SentryError, SyncPromise } from '@sentry/utils'; import { BaseTransport } from './base'; @@ -26,7 +26,7 @@ export class XHRTransport extends BaseTransport { */ private _sendRequest(sentryRequest: SentryRequest, originalPayload: Event | Session): PromiseLike { if (this._isRateLimited(sentryRequest.type)) { - this.recordLostEvent(Outcome.RateLimitBackoff, sentryRequest.type); + this.recordLostEvent('ratelimit_backoff', sentryRequest.type); return Promise.reject({ event: originalPayload, @@ -66,9 +66,9 @@ export class XHRTransport extends BaseTransport { .then(undefined, reason => { // It's either buffer rejection or any other xhr/fetch error, which are treated as NetworkError. if (reason instanceof SentryError) { - this.recordLostEvent(Outcome.QueueOverflow, sentryRequest.type); + this.recordLostEvent('queue_overflow', sentryRequest.type); } else { - this.recordLostEvent(Outcome.NetworkError, sentryRequest.type); + this.recordLostEvent('network_error', sentryRequest.type); } throw reason; }); diff --git a/packages/browser/test/unit/transports/base.test.ts b/packages/browser/test/unit/transports/base.test.ts index 660163527048..9180fbabc8f3 100644 --- a/packages/browser/test/unit/transports/base.test.ts +++ b/packages/browser/test/unit/transports/base.test.ts @@ -1,5 +1,3 @@ -import { Outcome } from '@sentry/types'; - import { BaseTransport } from '../../../src/transports/base'; const testDsn = 'https://123@sentry.io/42'; @@ -44,12 +42,12 @@ describe('BaseTransport', () => { it('sends beacon request when there are outcomes captured and visibility changed to `hidden`', () => { const transport = new SimpleTransport({ dsn: testDsn, sendClientReports: true }); - transport.recordLostEvent(Outcome.BeforeSend, 'event'); + transport.recordLostEvent('before_send', 'event'); visibilityState = 'hidden'; document.dispatchEvent(new Event('visibilitychange')); - const outcomes = [{ reason: Outcome.BeforeSend, category: 'error', quantity: 1 }]; + const outcomes = [{ reason: 'before_send', category: 'error', quantity: 1 }]; expect(sendBeaconSpy).toHaveBeenCalledWith( envelopeEndpoint, @@ -59,7 +57,7 @@ describe('BaseTransport', () => { it('doesnt send beacon request when there are outcomes captured, but visibility state did not change to `hidden`', () => { const transport = new SimpleTransport({ dsn: testDsn, sendClientReports: true }); - transport.recordLostEvent(Outcome.BeforeSend, 'event'); + transport.recordLostEvent('before_send', 'event'); visibilityState = 'visible'; document.dispatchEvent(new Event('visibilitychange')); @@ -70,21 +68,21 @@ describe('BaseTransport', () => { it('correctly serializes request with different categories/reasons pairs', () => { const transport = new SimpleTransport({ dsn: testDsn, sendClientReports: true }); - transport.recordLostEvent(Outcome.BeforeSend, 'event'); - transport.recordLostEvent(Outcome.BeforeSend, 'event'); - transport.recordLostEvent(Outcome.SampleRate, 'transaction'); - transport.recordLostEvent(Outcome.NetworkError, 'session'); - transport.recordLostEvent(Outcome.NetworkError, 'session'); - transport.recordLostEvent(Outcome.RateLimitBackoff, 'event'); + transport.recordLostEvent('before_send', 'event'); + transport.recordLostEvent('before_send', 'event'); + transport.recordLostEvent('sample_rate', 'transaction'); + transport.recordLostEvent('network_error', 'session'); + transport.recordLostEvent('network_error', 'session'); + transport.recordLostEvent('ratelimit_backoff', 'event'); visibilityState = 'hidden'; document.dispatchEvent(new Event('visibilitychange')); const outcomes = [ - { reason: Outcome.BeforeSend, category: 'error', quantity: 2 }, - { reason: Outcome.SampleRate, category: 'transaction', quantity: 1 }, - { reason: Outcome.NetworkError, category: 'session', quantity: 2 }, - { reason: Outcome.RateLimitBackoff, category: 'error', quantity: 1 }, + { reason: 'before_send', category: 'error', quantity: 2 }, + { reason: 'sample_rate', category: 'transaction', quantity: 1 }, + { reason: 'network_error', category: 'session', quantity: 2 }, + { reason: 'ratelimit_backoff', category: 'error', quantity: 1 }, ]; expect(sendBeaconSpy).toHaveBeenCalledWith( @@ -97,12 +95,12 @@ describe('BaseTransport', () => { const tunnel = 'https://hello.com/world'; const transport = new SimpleTransport({ dsn: testDsn, sendClientReports: true, tunnel }); - transport.recordLostEvent(Outcome.BeforeSend, 'event'); + transport.recordLostEvent('before_send', 'event'); visibilityState = 'hidden'; document.dispatchEvent(new Event('visibilitychange')); - const outcomes = [{ reason: Outcome.BeforeSend, category: 'error', quantity: 1 }]; + const outcomes = [{ reason: 'before_send', category: 'error', quantity: 1 }]; expect(sendBeaconSpy).toHaveBeenCalledWith( tunnel, diff --git a/packages/browser/test/unit/transports/fetch.test.ts b/packages/browser/test/unit/transports/fetch.test.ts index caa47cd76773..afb427b4026e 100644 --- a/packages/browser/test/unit/transports/fetch.test.ts +++ b/packages/browser/test/unit/transports/fetch.test.ts @@ -1,4 +1,3 @@ -import { Outcome } from '@sentry/types'; import { SentryError } from '@sentry/utils'; import { Event, Response, Transports } from '../../../src'; @@ -117,7 +116,7 @@ describe('FetchTransport', () => { try { await transport.sendEvent(eventPayload); } catch (_) { - expect(spy).toHaveBeenCalledWith(Outcome.NetworkError, 'event'); + expect(spy).toHaveBeenCalledWith('network_error', 'event'); } }); @@ -129,7 +128,7 @@ describe('FetchTransport', () => { try { await transport.sendEvent(transactionPayload); } catch (_) { - expect(spy).toHaveBeenCalledWith(Outcome.QueueOverflow, 'transaction'); + expect(spy).toHaveBeenCalledWith('queue_overflow', 'transaction'); } }); @@ -490,13 +489,13 @@ describe('FetchTransport', () => { try { await transport.sendEvent(eventPayload); } catch (_) { - expect(spy).toHaveBeenCalledWith(Outcome.RateLimitBackoff, 'event'); + expect(spy).toHaveBeenCalledWith('ratelimit_backoff', 'event'); } try { await transport.sendEvent(transactionPayload); } catch (_) { - expect(spy).toHaveBeenCalledWith(Outcome.RateLimitBackoff, 'transaction'); + expect(spy).toHaveBeenCalledWith('ratelimit_backoff', 'transaction'); } }); }); diff --git a/packages/browser/test/unit/transports/xhr.test.ts b/packages/browser/test/unit/transports/xhr.test.ts index 95b5c840c763..fcf7c26211da 100644 --- a/packages/browser/test/unit/transports/xhr.test.ts +++ b/packages/browser/test/unit/transports/xhr.test.ts @@ -1,4 +1,3 @@ -import { Outcome } from '@sentry/types'; import { SentryError } from '@sentry/utils'; import { fakeServer, SinonFakeServer } from 'sinon'; @@ -79,7 +78,7 @@ describe('XHRTransport', () => { try { await transport.sendEvent(eventPayload); } catch (_) { - expect(spy).toHaveBeenCalledWith(Outcome.NetworkError, 'event'); + expect(spy).toHaveBeenCalledWith('network_error', 'event'); } }); @@ -91,7 +90,7 @@ describe('XHRTransport', () => { try { await transport.sendEvent(transactionPayload); } catch (_) { - expect(spy).toHaveBeenCalledWith(Outcome.QueueOverflow, 'transaction'); + expect(spy).toHaveBeenCalledWith('queue_overflow', 'transaction'); } }); @@ -416,13 +415,13 @@ describe('XHRTransport', () => { try { await transport.sendEvent(eventPayload); } catch (_) { - expect(spy).toHaveBeenCalledWith(Outcome.RateLimitBackoff, 'event'); + expect(spy).toHaveBeenCalledWith('ratelimit_backoff', 'event'); } try { await transport.sendEvent(transactionPayload); } catch (_) { - expect(spy).toHaveBeenCalledWith(Outcome.RateLimitBackoff, 'transaction'); + expect(spy).toHaveBeenCalledWith('ratelimit_backoff', 'transaction'); } }); }); diff --git a/packages/core/src/baseclient.ts b/packages/core/src/baseclient.ts index 8e08eaaf43f8..af0d08187ee2 100644 --- a/packages/core/src/baseclient.ts +++ b/packages/core/src/baseclient.ts @@ -7,7 +7,6 @@ import { Integration, IntegrationClass, Options, - Outcome, SessionStatus, SeverityLevel, Transport, @@ -541,7 +540,7 @@ export abstract class BaseClient implement // 0.0 === 0% events are sent // Sampling for transaction happens somewhere else if (!isTransaction && typeof sampleRate === 'number' && Math.random() > sampleRate) { - recordLostEvent(Outcome.SampleRate, 'event'); + recordLostEvent('sample_rate', 'event'); return SyncPromise.reject( new SentryError( `Discarding event because it's not included in the random sample (sampling rate = ${sampleRate})`, @@ -552,7 +551,7 @@ export abstract class BaseClient implement return this._prepareEvent(event, scope, hint) .then(prepared => { if (prepared === null) { - recordLostEvent(Outcome.EventProcessor, event.type || 'event'); + recordLostEvent('event_processor', event.type || 'event'); throw new SentryError('An event processor returned null, will not send event.'); } @@ -566,7 +565,7 @@ export abstract class BaseClient implement }) .then(processedEvent => { if (processedEvent === null) { - recordLostEvent(Outcome.BeforeSend, event.type || 'event'); + recordLostEvent('before_send', event.type || 'event'); throw new SentryError('`beforeSend` returned `null`, will not send event.'); } diff --git a/packages/core/test/lib/base.test.ts b/packages/core/test/lib/base.test.ts index 2b91d3f8cd03..cd8d7f992fb4 100644 --- a/packages/core/test/lib/base.test.ts +++ b/packages/core/test/lib/base.test.ts @@ -1,5 +1,5 @@ import { Hub, Scope, Session } from '@sentry/hub'; -import { Event, Outcome, Span, Transport } from '@sentry/types'; +import { Event, Span, Transport } from '@sentry/types'; import { logger, SentryError, SyncPromise } from '@sentry/utils'; import * as integrationModule from '../../src/integration'; @@ -882,7 +882,7 @@ describe('BaseClient', () => { client.captureEvent({ message: 'hello' }, {}); - expect(recordLostEventSpy).toHaveBeenCalledWith(Outcome.BeforeSend, 'event'); + expect(recordLostEventSpy).toHaveBeenCalledWith('before_send', 'event'); }); test('eventProcessor can drop the even when it returns null', () => { @@ -914,7 +914,7 @@ describe('BaseClient', () => { scope.addEventProcessor(() => null); client.captureEvent({ message: 'hello' }, {}, scope); - expect(recordLostEventSpy).toHaveBeenCalledWith(Outcome.EventProcessor, 'event'); + expect(recordLostEventSpy).toHaveBeenCalledWith('event_processor', 'event'); }); test('eventProcessor sends an event and logs when it crashes', () => { @@ -958,7 +958,7 @@ describe('BaseClient', () => { ); client.captureEvent({ message: 'hello' }, {}); - expect(recordLostEventSpy).toHaveBeenCalledWith(Outcome.SampleRate, 'event'); + expect(recordLostEventSpy).toHaveBeenCalledWith('sample_rate', 'event'); }); }); diff --git a/packages/tracing/src/transaction.ts b/packages/tracing/src/transaction.ts index 45cb41357863..5143881ab159 100644 --- a/packages/tracing/src/transaction.ts +++ b/packages/tracing/src/transaction.ts @@ -2,7 +2,6 @@ import { getCurrentHub, Hub } from '@sentry/hub'; import { Event, Measurements, - Outcome, Transaction as TransactionInterface, TransactionContext, TransactionMetadata, @@ -107,7 +106,7 @@ export class Transaction extends SpanClass implements TransactionInterface { const client = this._hub.getClient(); const transport = client && client.getTransport && client.getTransport(); if (transport && transport.recordLostEvent) { - transport.recordLostEvent(Outcome.SampleRate, 'transaction'); + transport.recordLostEvent('sample_rate', 'transaction'); } return undefined; } diff --git a/packages/tracing/test/idletransaction.test.ts b/packages/tracing/test/idletransaction.test.ts index 07c545022ac1..b60fec726c54 100644 --- a/packages/tracing/test/idletransaction.test.ts +++ b/packages/tracing/test/idletransaction.test.ts @@ -1,6 +1,5 @@ import { BrowserClient, Transports } from '@sentry/browser'; import { Hub } from '@sentry/hub'; -import { Outcome } from '@sentry/types'; import { DEFAULT_IDLE_TIMEOUT, @@ -174,7 +173,7 @@ describe('IdleTransaction', () => { transaction.initSpanRecorder(10); transaction.finish(transaction.startTimestamp + 10); - expect(spy).toHaveBeenCalledWith(Outcome.SampleRate, 'transaction'); + expect(spy).toHaveBeenCalledWith('sample_rate', 'transaction'); }); describe('_initTimeout', () => { diff --git a/packages/types/src/transport.ts b/packages/types/src/transport.ts index 40c26c146554..a1ba2983b1a3 100644 --- a/packages/types/src/transport.ts +++ b/packages/types/src/transport.ts @@ -5,14 +5,13 @@ import { Response } from './response'; import { SdkMetadata } from './sdkmetadata'; import { Session, SessionAggregates } from './session'; -export enum Outcome { - BeforeSend = 'before_send', - EventProcessor = 'event_processor', - NetworkError = 'network_error', - QueueOverflow = 'queue_overflow', - RateLimitBackoff = 'ratelimit_backoff', - SampleRate = 'sample_rate', -} +export type Outcome = + | 'before_send' + | 'event_processor' + | 'network_error' + | 'queue_overflow' + | 'ratelimit_backoff' + | 'sample_rate'; /** Transport used sending data to Sentry */ export interface Transport { diff --git a/packages/types/src/transportoutcome.ts b/packages/types/src/transportoutcome.ts new file mode 100644 index 000000000000..1fda3d9a447c --- /dev/null +++ b/packages/types/src/transportoutcome.ts @@ -0,0 +1,11 @@ +/** JSDoc + * @deprecated Use string literals - if you require type casting, cast to Outcome type + */ +export enum Outcome { + BeforeSend = 'before_send', + EventProcessor = 'event_processor', + NetworkError = 'network_error', + QueueOverflow = 'queue_overflow', + RateLimitBackoff = 'ratelimit_backoff', + SampleRate = 'sample_rate', +}