MCPcopy Index your code
hub / github.com/getsentry/sentry-javascript / updateRateLimits

Function updateRateLimits

packages/core/src/utils/ratelimit.ts:53–108  ·  view source on GitHub ↗
(
  limits: RateLimits,
  { statusCode, headers }: TransportMakeRequestResponse,
  now: number = safeDateNow(),
)

Source from the content-addressed store, hash-verified

51 * @return the updated RateLimits object.
52 */
53export function updateRateLimits(
54 limits: RateLimits,
55 { statusCode, headers }: TransportMakeRequestResponse,
56 now: number = safeDateNow(),
57): RateLimits {
58 const updatedRateLimits: RateLimits = {
59 ...limits,
60 };
61
62 // "The name is case-insensitive."
63 // https://developer.mozilla.org/en-US/docs/Web/API/Headers/get
64 const rateLimitHeader = headers?.['x-sentry-rate-limits'];
65 const retryAfterHeader = headers?.['retry-after'];
66
67 if (rateLimitHeader) {
68 /**
69 * rate limit headers are of the form
70 * <header>,<header>,..
71 * where each <header> is of the form
72 * <retry_after>: <categories>: <scope>: <reason_code>: <namespaces>
73 * where
74 * <retry_after> is a delay in seconds
75 * <categories> is the event type(s) (error, transaction, etc) being rate limited and is of the form
76 * <category>;<category>;...
77 * <scope> is what's being limited (org, project, or key) - ignored by SDK
78 * <reason_code> is an arbitrary string like "org_quota" - ignored by SDK
79 * <namespaces> Semicolon-separated list of metric namespace identifiers. Defines which namespace(s) will be affected.
80 * Only present if rate limit applies to the metric_bucket data category.
81 */
82 for (const limit of rateLimitHeader.trim().split(',')) {
83 const [retryAfter, categories, , , namespaces] = limit.split(':', 5) as [string, ...string[]];
84 const headerDelay = parseInt(retryAfter, 10);
85 const delay = (!isNaN(headerDelay) ? headerDelay : 60) * 1000; // 60sec default
86 if (!categories) {
87 updatedRateLimits.all = now + delay;
88 } else {
89 for (const category of categories.split(';')) {
90 if (category === 'metric_bucket') {
91 // namespaces will be present when category === 'metric_bucket'
92 if (!namespaces || namespaces.split(';').includes('custom')) {
93 updatedRateLimits[category] = now + delay;
94 }
95 } else {
96 updatedRateLimits[category] = now + delay;
97 }
98 }
99 }
100 }
101 } else if (retryAfterHeader) {
102 updatedRateLimits.all = now + parseRetryAfterHeader(retryAfterHeader, now);
103 } else if (statusCode === 429) {
104 updatedRateLimits.all = now + 60 * 1000;
105 }
106
107 return updatedRateLimits;
108}

Callers 3

ratelimit.test.tsFile · 0.90
requestTaskFunction · 0.90
sendReplayRequestFunction · 0.90

Calls 2

safeDateNowFunction · 0.90
parseRetryAfterHeaderFunction · 0.85

Tested by

no test coverage detected