diff --git a/packages/core/src/transports/offline.ts b/packages/core/src/transports/offline.ts index 0b99baba1e4b..34f8c438529d 100644 --- a/packages/core/src/transports/offline.ts +++ b/packages/core/src/transports/offline.ts @@ -38,8 +38,19 @@ export interface OfflineTransportOptions extends InternalBaseTransportOptions { * @param envelope The envelope that failed to send. * @param error The error that occurred. * @param retryDelay The current retry delay in milliseconds. + * @returns Whether the envelope should be stored. */ shouldStore?: (envelope: Envelope, error: Error, retryDelay: number) => boolean | Promise; + + /** + * Should an attempt be made to send the envelope to Sentry. + * + * If this function is supplied and returns false, `shouldStore` will be called to determine if the envelope should be stored. + * + * @param envelope The envelope that will be sent. + * @returns Whether we should attempt to send the envelope + */ + shouldSend?: (envelope: Envelope) => boolean | Promise; } type Timer = number | { unref?: () => void }; @@ -128,6 +139,10 @@ export function makeOfflineTransport( } try { + if (options.shouldSend && (await options.shouldSend(envelope)) === false) { + throw new Error('Envelope not sent because `shouldSend` callback returned false'); + } + const result = await transport.send(envelope); let delay = MIN_DELAY; diff --git a/packages/core/test/lib/transports/offline.test.ts b/packages/core/test/lib/transports/offline.test.ts index 0dfc550fcd38..cf3b414c0d0e 100644 --- a/packages/core/test/lib/transports/offline.test.ts +++ b/packages/core/test/lib/transports/offline.test.ts @@ -353,6 +353,27 @@ describe('makeOfflineTransport', () => { expect(getCalls()).toEqual([]); }); + it('shouldSend can stop envelopes from being sent', async () => { + const { getCalls, store } = createTestStore(); + const { getSendCount, baseTransport } = createTestTransport(new Error()); + let queuedCount = 0; + const transport = makeOfflineTransport(baseTransport)({ + ...transportOptions, + createStore: store, + shouldSend: () => false, + shouldStore: () => { + queuedCount += 1; + return true; + }, + }); + const result = transport.send(ERROR_ENVELOPE); + + await expect(result).resolves.toEqual({}); + expect(queuedCount).toEqual(1); + expect(getSendCount()).toEqual(0); + expect(getCalls()).toEqual(['push']); + }); + it('should not store client report envelopes on send failure', async () => { const { getCalls, store } = createTestStore(); const { getSendCount, baseTransport } = createTestTransport(new Error());