diff --git a/app/lib/service/rate_limit/rate_limit.dart b/app/lib/service/rate_limit/rate_limit.dart index ecee04b402..8bd0fd3abd 100644 --- a/app/lib/service/rate_limit/rate_limit.dart +++ b/app/lib/service/rate_limit/rate_limit.dart @@ -82,6 +82,7 @@ Future _verifyRateLimit({ List? auditEntriesFromLastDay; Future check({ + required String operation, required Duration window, required int? maxCount, required String windowAsText, @@ -94,6 +95,7 @@ Future _verifyRateLimit({ final current = await entry.get(); if (current != null && current.isAfter(clock.now())) { throw RateLimitException( + operation: operation, maxCount: maxCount, window: window, windowAsText: windowAsText, @@ -117,6 +119,7 @@ Future _verifyRateLimit({ .reduce((a, b) => a.isBefore(b) ? a : b); await entry.set(firstTimestamp.add(window), window); throw RateLimitException( + operation: operation, maxCount: maxCount, window: window, windowAsText: windowAsText, @@ -125,16 +128,19 @@ Future _verifyRateLimit({ } await check( + operation: rateLimit.operation, window: Duration(minutes: 2), maxCount: rateLimit.burst, windowAsText: 'last few minutes', ); await check( + operation: rateLimit.operation, window: Duration(hours: 1), maxCount: rateLimit.hourly, windowAsText: 'last hour', ); await check( + operation: rateLimit.operation, window: Duration(days: 1), maxCount: rateLimit.daily, windowAsText: 'last day', diff --git a/app/lib/shared/exceptions.dart b/app/lib/shared/exceptions.dart index 092b0e2940..aba68ad60c 100644 --- a/app/lib/shared/exceptions.dart +++ b/app/lib/shared/exceptions.dart @@ -343,15 +343,18 @@ class OperationForbiddenException extends ResponseException { /// Thrown when the operation is rejected because a rate limit is reached. class RateLimitException extends ResponseException { RateLimitException({ + required String operation, required int maxCount, required String windowAsText, required Duration window, }) : super._( 429, 'RateLimit', - 'The operation is blocked, as rate limit in the current window ' + 'The "$operation" operation is blocked, as its rate limit ' 'has been reached ($maxCount in the $windowAsText). ' - 'Please try again later.', + 'Please try again later. ' + 'Please report the issue on https://github.com/dart-lang/pub-dev/issues/new ' + 'if you think the limit should be increased to accommodate your use case.', headers: { 'Retry-After': '${window.inSeconds}', },