diff --git a/packages/core/src/types/datacategory.ts b/packages/core/src/types/datacategory.ts index ad1e61732816..f778efd2f348 100644 --- a/packages/core/src/types/datacategory.ts +++ b/packages/core/src/types/datacategory.ts @@ -33,6 +33,6 @@ export type DataCategory = // Log bytes stored (unused for rate limiting) | 'log_byte' // Metric event - | 'metric' + | 'trace_metric' // Unknown data category | 'unknown'; diff --git a/packages/core/src/utils/envelope.ts b/packages/core/src/utils/envelope.ts index bcb34359f23c..1e216717e978 100644 --- a/packages/core/src/utils/envelope.ts +++ b/packages/core/src/utils/envelope.ts @@ -208,7 +208,7 @@ export function createAttachmentEnvelopeItem(attachment: Attachment): Attachment type OverriddenItemType = Exclude; // Map of envelope item types to data categories where the category differs from the type. -// Types that map to themselves (session, attachment, transaction, profile, feedback, span, metric) fall through. +// Types that map to themselves (session, attachment, transaction, profile, feedback, span, trace_metric) fall through. const DATA_CATEGORY_OVERRIDES: Record = { sessions: 'session', event: 'error', @@ -220,7 +220,7 @@ const DATA_CATEGORY_OVERRIDES: Record = { check_in: 'monitor', raw_security: 'security', log: 'log_item', - trace_metric: 'metric', + metric: 'trace_metric', }; function _isOverriddenType(type: EnvelopeItemType): type is OverriddenItemType { diff --git a/packages/core/test/lib/transports/base.test.ts b/packages/core/test/lib/transports/base.test.ts index 0b761d5d6708..e659ee8e24e6 100644 --- a/packages/core/test/lib/transports/base.test.ts +++ b/packages/core/test/lib/transports/base.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from 'vitest'; import { createTransport } from '../../../src/transports/base'; import type { ClientReport } from '../../../src/types/clientreport'; -import type { AttachmentItem, EventEnvelope, EventItem } from '../../../src/types/envelope'; +import type { AttachmentItem, Envelope, EventEnvelope, EventItem } from '../../../src/types/envelope'; import type { TransportMakeRequestResponse } from '../../../src/types/transport'; import { createClientReportEnvelope } from '../../../src/utils/clientreport'; import { createEnvelope, serializeEnvelope } from '../../../src/utils/envelope'; @@ -324,6 +324,34 @@ describe('createTransport', () => { expect(requestExecutor).toHaveBeenCalledTimes(1); expect(recordDroppedEventCallback).not.toHaveBeenCalled(); }); + + it('back-off using X-Sentry-Rate-Limits with trace_metric category', async () => { + const { retryAfterSeconds, beforeLimit, withinLimit } = setRateLimitTimes(); + const [transport, , requestExecutor, recordDroppedEventCallback] = createTestTransport({ + headers: { + 'x-sentry-rate-limits': `${retryAfterSeconds}:trace_metric:scope`, + 'retry-after': null, + }, + }); + + const dateNowSpy = vi.spyOn(Date, 'now').mockImplementation(() => beforeLimit); + + await transport.send(ERROR_ENVELOPE); + requestExecutor.mockClear(); + + dateNowSpy.mockImplementation(() => withinLimit); + + await transport.send( + createEnvelope({ sent_at: '123' }, [ + [ + { type: 'trace_metric', item_count: 2, content_type: 'application/vnd.sentry.items.trace-metric+json' }, + { items: [] }, + ], + ] as Envelope[1]), + ); + expect(requestExecutor).not.toHaveBeenCalled(); + expect(recordDroppedEventCallback).toHaveBeenCalledWith('ratelimit_backoff', 'trace_metric'); + }); }); describe('Client Reports', () => {