@@ -19,15 +19,18 @@ import {
1919} from '@sentry/types' ;
2020import {
2121 createClientReportEnvelope ,
22+ disabledUntil ,
2223 dsnToString ,
2324 eventStatusFromHttpCode ,
2425 getGlobalObject ,
2526 isDebugBuild ,
27+ isRateLimited ,
2628 logger ,
2729 makePromiseBuffer ,
28- parseRetryAfterHeader ,
2930 PromiseBuffer ,
31+ RateLimits ,
3032 serializeEnvelope ,
33+ updateRateLimits ,
3134} from '@sentry/utils' ;
3235
3336import { sendReport } from './utils' ;
@@ -53,7 +56,7 @@ export abstract class BaseTransport implements Transport {
5356 protected readonly _buffer : PromiseBuffer < SentryResponse > = makePromiseBuffer ( 30 ) ;
5457
5558 /** Locks transport after receiving rate limits in a response */
56- protected readonly _rateLimits : Record < string , Date > = { } ;
59+ protected _rateLimits : RateLimits = { } ;
5760
5861 protected _outcomes : { [ key : string ] : number } = { } ;
5962
@@ -165,13 +168,12 @@ export abstract class BaseTransport implements Transport {
165168 reject : ( reason ?: unknown ) => void ;
166169 } ) : void {
167170 const status = eventStatusFromHttpCode ( response . status ) ;
168- /**
169- * "The name is case-insensitive."
170- * https://developer.mozilla.org/en-US/docs/Web/API/Headers/get
171- */
172- const limited = this . _handleRateLimit ( headers ) ;
173- if ( limited && isDebugBuild ( ) ) {
174- logger . warn ( `Too many ${ requestType } requests, backing off until: ${ this . _disabledUntil ( requestType ) } ` ) ;
171+
172+ this . _rateLimits = updateRateLimits ( this . _rateLimits , headers ) ;
173+ if ( isRateLimited ( this . _rateLimits , requestType ) && isDebugBuild ( ) ) {
174+ logger . warn (
175+ `Too many ${ requestType } requests, backing off until: ${ disabledUntil ( this . _rateLimits , requestType ) } ` ,
176+ ) ;
175177 }
176178
177179 if ( status === 'success' ) {
@@ -184,52 +186,21 @@ export abstract class BaseTransport implements Transport {
184186
185187 /**
186188 * Gets the time that given category is disabled until for rate limiting
189+ *
190+ * @deprecated Please use `disabledUntil` from @sentry/utils
187191 */
188- protected _disabledUntil ( requestType : SentryRequestType ) : Date {
192+ protected _disabledUntil ( requestType : SentryRequestType ) : number {
189193 const category = requestTypeToCategory ( requestType ) ;
190- return this . _rateLimits [ category ] || this . _rateLimits . all ;
194+ return disabledUntil ( this . _rateLimits , category ) ;
191195 }
192196
193197 /**
194198 * Checks if a category is rate limited
199+ *
200+ * @deprecated Please use `isRateLimited` from @sentry/utils
195201 */
196202 protected _isRateLimited ( requestType : SentryRequestType ) : boolean {
197- return this . _disabledUntil ( requestType ) > new Date ( Date . now ( ) ) ;
198- }
199-
200- /**
201- * Sets internal _rateLimits from incoming headers. Returns true if headers contains a non-empty rate limiting header.
202- */
203- protected _handleRateLimit ( headers : Record < string , string | null > ) : boolean {
204- const now = Date . now ( ) ;
205- const rlHeader = headers [ 'x-sentry-rate-limits' ] ;
206- const raHeader = headers [ 'retry-after' ] ;
207-
208- if ( rlHeader ) {
209- // rate limit headers are of the form
210- // <header>,<header>,..
211- // where each <header> is of the form
212- // <retry_after>: <categories>: <scope>: <reason_code>
213- // where
214- // <retry_after> is a delay in ms
215- // <categories> is the event type(s) (error, transaction, etc) being rate limited and is of the form
216- // <category>;<category>;...
217- // <scope> is what's being limited (org, project, or key) - ignored by SDK
218- // <reason_code> is an arbitrary string like "org_quota" - ignored by SDK
219- for ( const limit of rlHeader . trim ( ) . split ( ',' ) ) {
220- const parameters = limit . split ( ':' , 2 ) ;
221- const headerDelay = parseInt ( parameters [ 0 ] , 10 ) ;
222- const delay = ( ! isNaN ( headerDelay ) ? headerDelay : 60 ) * 1000 ; // 60sec default
223- for ( const category of parameters [ 1 ] . split ( ';' ) ) {
224- this . _rateLimits [ category || 'all' ] = new Date ( now + delay ) ;
225- }
226- }
227- return true ;
228- } else if ( raHeader ) {
229- this . _rateLimits . all = new Date ( now + parseRetryAfterHeader ( raHeader , now ) ) ;
230- return true ;
231- }
232- return false ;
203+ return isRateLimited ( this . _rateLimits , requestType ) ;
233204 }
234205
235206 protected abstract _sendRequest (
0 commit comments