diff --git a/docs/en/framework/infrastructure/operation-rate-limiting.md b/docs/en/framework/infrastructure/operation-rate-limiting.md
index 89e808d121..736152444f 100644
--- a/docs/en/framework/infrastructure/operation-rate-limiting.md
+++ b/docs/en/framework/infrastructure/operation-rate-limiting.md
@@ -274,6 +274,15 @@ When a rate limit is exceeded, `CheckAsync` throws `AbpOperationRateLimitingExce
* Extends `BusinessException` and implements `IHasHttpStatusCode` with status code **429** (Too Many Requests).
* Is automatically handled by ABP's exception handling pipeline and serialized into the HTTP response.
+The exception uses one of two error codes depending on the policy type:
+
+| Error Code | Constant | When Used |
+|---|---|---|
+| `Volo.Abp.OperationRateLimiting:010001` | `AbpOperationRateLimitingErrorCodes.ExceedLimit` | Regular rate limit exceeded (has a retry-after window) |
+| `Volo.Abp.OperationRateLimiting:010002` | `AbpOperationRateLimitingErrorCodes.ExceedLimitPermanently` | Ban policy (`maxCount: 0`, permanently denied) |
+
+You can override the error code per policy using `WithErrorCode()`. When a custom code is set, it is always used regardless of the policy type.
+
The exception includes the following data properties:
| Key | Type | Description |
@@ -282,9 +291,9 @@ The exception includes the following data properties:
| `MaxCount` | int | Maximum allowed count |
| `CurrentCount` | int | Current usage count |
| `RemainingCount` | int | Remaining allowed count |
-| `RetryAfterSeconds` | int | Seconds until the window resets |
-| `RetryAfterMinutes` | int | Minutes until the window resets (rounded down) |
-| `RetryAfter` | string | Localized retry-after description (e.g., "5 minutes") |
+| `RetryAfterSeconds` | int | Seconds until the window resets (`0` for ban policies) |
+| `RetryAfterMinutes` | int | Minutes until the window resets, rounded down (`0` for ban policies) |
+| `RetryAfter` | string | Localized retry-after description (e.g., "5 minutes"); absent for ban policies |
| `WindowDurationSeconds` | int | Total window duration in seconds |
| `WindowDescription` | string | Localized window description |
| `RuleDetails` | List | Per-rule details (for multi-rule policies) |
@@ -329,7 +338,7 @@ public override void ConfigureServices(ServiceConfigurationContext context)
### Ban Policy (maxCount: 0)
-Setting `maxCount` to `0` creates a ban policy that permanently denies all requests regardless of the window duration. The `RetryAfter` value will be `null` since there is no window to wait for:
+Setting `maxCount` to `0` creates a ban policy that permanently denies all requests regardless of the window duration. The `RetryAfter` value will be `null` since there is no window to wait for. The exception uses the error code `Volo.Abp.OperationRateLimiting:010002` (`AbpOperationRateLimitingErrorCodes.ExceedLimitPermanently`) with the message "Operation rate limit exceeded. This request is permanently denied.":
````csharp
options.AddPolicy("BlockedUser", policy =>
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingErrorCodes.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingErrorCodes.cs
index 5ff8d88b5a..ba2bb5c189 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingErrorCodes.cs
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingErrorCodes.cs
@@ -3,7 +3,12 @@ namespace Volo.Abp.OperationRateLimiting;
public static class AbpOperationRateLimitingErrorCodes
{
///
- /// Default error code for rate limit exceeded.
+ /// Default error code for rate limit exceeded (with a retry-after window).
///
public const string ExceedLimit = "Volo.Abp.OperationRateLimiting:010001";
+
+ ///
+ /// Error code for ban policy (maxCount: 0) where requests are permanently denied.
+ ///
+ public const string ExceedLimitPermanently = "Volo.Abp.OperationRateLimiting:010002";
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Exceptions/AbpOperationRateLimitingException.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Exceptions/AbpOperationRateLimitingException.cs
index 9872d26e76..88cfb2c6ff 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Exceptions/AbpOperationRateLimitingException.cs
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Exceptions/AbpOperationRateLimitingException.cs
@@ -15,7 +15,7 @@ public class AbpOperationRateLimitingException : BusinessException, IHasHttpStat
string policyName,
OperationRateLimitingResult result,
string? errorCode = null)
- : base(code: errorCode ?? AbpOperationRateLimitingErrorCodes.ExceedLimit)
+ : base(code: errorCode ?? ResolveDefaultErrorCode(result))
{
PolicyName = policyName;
Result = result;
@@ -38,4 +38,11 @@ public class AbpOperationRateLimitingException : BusinessException, IHasHttpStat
{
WithData("WindowDescription", formattedWindowDescription);
}
+
+ private static string ResolveDefaultErrorCode(OperationRateLimitingResult result)
+ {
+ return result.RetryAfter.HasValue
+ ? AbpOperationRateLimitingErrorCodes.ExceedLimit
+ : AbpOperationRateLimitingErrorCodes.ExceedLimitPermanently;
+ }
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/ar.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/ar.json
index 46b937bb99..3ca1c8f042 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/ar.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/ar.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} ساعة/ساعات و {1} دقيقة/دقائق",
"RetryAfter:Minutes": "{0} دقيقة/دقائق",
"RetryAfter:MinutesAndSeconds": "{0} دقيقة/دقائق و {1} ثانية/ثوان",
- "RetryAfter:Seconds": "{0} ثانية/ثوان"
+ "RetryAfter:Seconds": "{0} ثانية/ثوان",
+ "Volo.Abp.OperationRateLimiting:010002": "تم تجاوز حد معدل العملية. هذا الطلب مرفوض بشكل دائم."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/cs.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/cs.json
index 205d229c10..44cfb86437 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/cs.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/cs.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} hodina/hodiny/hodin a {1} minuta/minuty/minut",
"RetryAfter:Minutes": "{0} minuta/minuty/minut",
"RetryAfter:MinutesAndSeconds": "{0} minuta/minuty/minut a {1} sekunda/sekundy/sekund",
- "RetryAfter:Seconds": "{0} sekunda/sekundy/sekund"
+ "RetryAfter:Seconds": "{0} sekunda/sekundy/sekund",
+ "Volo.Abp.OperationRateLimiting:010002": "Byl překročen limit četnosti operace. Tento požadavek je trvale zamítnut."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/de.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/de.json
index 3313e0156d..44286d68a8 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/de.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/de.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} Stunde(n) und {1} Minute(n)",
"RetryAfter:Minutes": "{0} Minute(n)",
"RetryAfter:MinutesAndSeconds": "{0} Minute(n) und {1} Sekunde(n)",
- "RetryAfter:Seconds": "{0} Sekunde(n)"
+ "RetryAfter:Seconds": "{0} Sekunde(n)",
+ "Volo.Abp.OperationRateLimiting:010002": "Das Vorgangshäufigkeitslimit wurde überschritten. Diese Anfrage wird dauerhaft abgelehnt."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/el.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/el.json
index 53359d6fa8..a688778eb5 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/el.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/el.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} ώρα/ες και {1} λεπτό/ά",
"RetryAfter:Minutes": "{0} λεπτό/ά",
"RetryAfter:MinutesAndSeconds": "{0} λεπτό/ά και {1} δευτερόλεπτο/α",
- "RetryAfter:Seconds": "{0} δευτερόλεπτο/α"
+ "RetryAfter:Seconds": "{0} δευτερόλεπτο/α",
+ "Volo.Abp.OperationRateLimiting:010002": "Υπερβλήθηκε το όριο συχνότητας λειτουργίας. Αυτό το αίτημα απορρίπτεται μόνιμα."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/en-GB.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/en-GB.json
index de3b1de3a3..4eab97f134 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/en-GB.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/en-GB.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} hour(s) and {1} minute(s)",
"RetryAfter:Minutes": "{0} minute(s)",
"RetryAfter:MinutesAndSeconds": "{0} minute(s) and {1} second(s)",
- "RetryAfter:Seconds": "{0} second(s)"
+ "RetryAfter:Seconds": "{0} second(s)",
+ "Volo.Abp.OperationRateLimiting:010002": "Operation rate limit exceeded. This request is permanently denied."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/en.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/en.json
index 0abcff4386..fc41cabc2f 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/en.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/en.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} hour(s) and {1} minute(s)",
"RetryAfter:Minutes": "{0} minute(s)",
"RetryAfter:MinutesAndSeconds": "{0} minute(s) and {1} second(s)",
- "RetryAfter:Seconds": "{0} second(s)"
+ "RetryAfter:Seconds": "{0} second(s)",
+ "Volo.Abp.OperationRateLimiting:010002": "Operation rate limit exceeded. This request is permanently denied."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/es.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/es.json
index 299ccd0fa2..ce13a9bceb 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/es.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/es.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} hora(s) y {1} minuto(s)",
"RetryAfter:Minutes": "{0} minuto(s)",
"RetryAfter:MinutesAndSeconds": "{0} minuto(s) y {1} segundo(s)",
- "RetryAfter:Seconds": "{0} segundo(s)"
+ "RetryAfter:Seconds": "{0} segundo(s)",
+ "Volo.Abp.OperationRateLimiting:010002": "Se superó el límite de frecuencia de operación. Esta solicitud está permanentemente denegada."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/fa.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/fa.json
index 09c7f21376..0f200b5472 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/fa.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/fa.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} ساعت و {1} دقیقه",
"RetryAfter:Minutes": "{0} دقیقه",
"RetryAfter:MinutesAndSeconds": "{0} دقیقه و {1} ثانیه",
- "RetryAfter:Seconds": "{0} ثانیه"
+ "RetryAfter:Seconds": "{0} ثانیه",
+ "Volo.Abp.OperationRateLimiting:010002": "محدودیت نرخ عملیات از حد مجاز فراتر رفت. این درخواست به طور دائمی رد شده است."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/fi.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/fi.json
index de379d5989..bcb88bf9ed 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/fi.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/fi.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} tunti/tuntia ja {1} minuutti/minuuttia",
"RetryAfter:Minutes": "{0} minuutti/minuuttia",
"RetryAfter:MinutesAndSeconds": "{0} minuutti/minuuttia ja {1} sekunti/sekuntia",
- "RetryAfter:Seconds": "{0} sekunti/sekuntia"
+ "RetryAfter:Seconds": "{0} sekunti/sekuntia",
+ "Volo.Abp.OperationRateLimiting:010002": "Toiminnan nopeusraja ylitettiin. Tämä pyyntö on pysyvästi hylätty."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/fr.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/fr.json
index b531b036f0..dca23d7a80 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/fr.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/fr.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} heure(s) et {1} minute(s)",
"RetryAfter:Minutes": "{0} minute(s)",
"RetryAfter:MinutesAndSeconds": "{0} minute(s) et {1} seconde(s)",
- "RetryAfter:Seconds": "{0} seconde(s)"
+ "RetryAfter:Seconds": "{0} seconde(s)",
+ "Volo.Abp.OperationRateLimiting:010002": "La limite de fréquence d'opération a été dépassée. Cette demande est définitivement refusée."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/hi.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/hi.json
index 6a53a5106e..a84a1e44a8 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/hi.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/hi.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} घंटा/घंटे और {1} मिनट",
"RetryAfter:Minutes": "{0} मिनट",
"RetryAfter:MinutesAndSeconds": "{0} मिनट और {1} सेकंड",
- "RetryAfter:Seconds": "{0} सेकंड"
+ "RetryAfter:Seconds": "{0} सेकंड",
+ "Volo.Abp.OperationRateLimiting:010002": "ऑपरेशन दर सीमा पार हो गई। यह अनुरोध स्थायी रूप से अस्वीकृत है।"
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/hr.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/hr.json
index d8a0ce4a18..c6597be78e 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/hr.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/hr.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} sat/i i {1} minuta/e",
"RetryAfter:Minutes": "{0} minuta/e",
"RetryAfter:MinutesAndSeconds": "{0} minuta/e i {1} sekunda/e",
- "RetryAfter:Seconds": "{0} sekunda/e"
+ "RetryAfter:Seconds": "{0} sekunda/e",
+ "Volo.Abp.OperationRateLimiting:010002": "Prekoračeno je ograničenje brzine operacije. Ovaj zahtjev je trajno odbijen."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/hu.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/hu.json
index b1ece6246a..f72dfea397 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/hu.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/hu.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} óra és {1} perc",
"RetryAfter:Minutes": "{0} perc",
"RetryAfter:MinutesAndSeconds": "{0} perc és {1} másodperc",
- "RetryAfter:Seconds": "{0} másodperc"
+ "RetryAfter:Seconds": "{0} másodperc",
+ "Volo.Abp.OperationRateLimiting:010002": "A műveleti ráta korlátja túllépve. Ez a kérés véglegesen elutasítva."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/is.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/is.json
index 45c6255ee1..cce36e42cd 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/is.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/is.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} klukkustund(ir) og {1} mínúta/úr",
"RetryAfter:Minutes": "{0} mínúta/úr",
"RetryAfter:MinutesAndSeconds": "{0} mínúta/úr og {1} sekúnda/úr",
- "RetryAfter:Seconds": "{0} sekúnda/úr"
+ "RetryAfter:Seconds": "{0} sekúnda/úr",
+ "Volo.Abp.OperationRateLimiting:010002": "Farið var yfir takmörk á rekstrartíðni. Þessari beiðni er varanlega hafnað."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/it.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/it.json
index f93fb278bf..f602fd1a66 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/it.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/it.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} ora/e e {1} minuto/i",
"RetryAfter:Minutes": "{0} minuto/i",
"RetryAfter:MinutesAndSeconds": "{0} minuto/i e {1} secondo/i",
- "RetryAfter:Seconds": "{0} secondo/i"
+ "RetryAfter:Seconds": "{0} secondo/i",
+ "Volo.Abp.OperationRateLimiting:010002": "Limite di frequenza operazione superato. Questa richiesta è permanentemente negata."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/nl.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/nl.json
index a733537123..bb21e7f313 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/nl.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/nl.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} uur en {1} minuut/minuten",
"RetryAfter:Minutes": "{0} minuut/minuten",
"RetryAfter:MinutesAndSeconds": "{0} minuut/minuten en {1} seconde(n)",
- "RetryAfter:Seconds": "{0} seconde(n)"
+ "RetryAfter:Seconds": "{0} seconde(n)",
+ "Volo.Abp.OperationRateLimiting:010002": "Het bewerkingsfrequentielimiet is overschreden. Dit verzoek wordt permanent geweigerd."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/pl-PL.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/pl-PL.json
index 72d6c905a5..e4503f6aa7 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/pl-PL.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/pl-PL.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} godzina/godzin i {1} minuta/minut",
"RetryAfter:Minutes": "{0} minuta/minut",
"RetryAfter:MinutesAndSeconds": "{0} minuta/minut i {1} sekunda/sekund",
- "RetryAfter:Seconds": "{0} sekunda/sekund"
+ "RetryAfter:Seconds": "{0} sekunda/sekund",
+ "Volo.Abp.OperationRateLimiting:010002": "Przekroczono limit częstotliwości operacji. To żądanie jest trwale odrzucone."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/pt-BR.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/pt-BR.json
index 412f7f2389..fb6f873805 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/pt-BR.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/pt-BR.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} hora(s) e {1} minuto(s)",
"RetryAfter:Minutes": "{0} minuto(s)",
"RetryAfter:MinutesAndSeconds": "{0} minuto(s) e {1} segundo(s)",
- "RetryAfter:Seconds": "{0} segundo(s)"
+ "RetryAfter:Seconds": "{0} segundo(s)",
+ "Volo.Abp.OperationRateLimiting:010002": "Limite de taxa de operação excedido. Esta solicitação está permanentemente negada."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/ro-RO.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/ro-RO.json
index cef165fa42..178042fa85 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/ro-RO.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/ro-RO.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} oră/ore și {1} minut(e)",
"RetryAfter:Minutes": "{0} minut(e)",
"RetryAfter:MinutesAndSeconds": "{0} minut(e) și {1} secundă/secunde",
- "RetryAfter:Seconds": "{0} secundă/secunde"
+ "RetryAfter:Seconds": "{0} secundă/secunde",
+ "Volo.Abp.OperationRateLimiting:010002": "Limita de rată a operației a fost depășită. Această solicitare este permanent refuzată."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/ru.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/ru.json
index dc4ddf6db6..5260a9c90c 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/ru.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/ru.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} час/часов и {1} минута/минут",
"RetryAfter:Minutes": "{0} минута/минут",
"RetryAfter:MinutesAndSeconds": "{0} минута/минут и {1} секунда/секунд",
- "RetryAfter:Seconds": "{0} секунда/секунд"
+ "RetryAfter:Seconds": "{0} секунда/секунд",
+ "Volo.Abp.OperationRateLimiting:010002": "Превышен лимит частоты операций. Этот запрос постоянно отклонён."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/sk.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/sk.json
index bd849adb48..73cdbb2b5d 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/sk.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/sk.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} hodina/hodín a {1} minúta/minút",
"RetryAfter:Minutes": "{0} minúta/minút",
"RetryAfter:MinutesAndSeconds": "{0} minúta/minút a {1} sekunda/sekúnd",
- "RetryAfter:Seconds": "{0} sekunda/sekúnd"
+ "RetryAfter:Seconds": "{0} sekunda/sekúnd",
+ "Volo.Abp.OperationRateLimiting:010002": "Bol prekročený limit frekvencie operácie. Táto požiadavka je trvalo zamietnutá."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/sl.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/sl.json
index eb6c54980e..333f51efb5 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/sl.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/sl.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} ura/ur in {1} minuta/minut",
"RetryAfter:Minutes": "{0} minuta/minut",
"RetryAfter:MinutesAndSeconds": "{0} minuta/minut in {1} sekunda/sekund",
- "RetryAfter:Seconds": "{0} sekunda/sekund"
+ "RetryAfter:Seconds": "{0} sekunda/sekund",
+ "Volo.Abp.OperationRateLimiting:010002": "Prekoračena je omejitev hitrosti operacije. Ta zahteva je trajno zavrnjena."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/sv.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/sv.json
index 562ba3d586..ef5172867c 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/sv.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/sv.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} timme/timmar och {1} minut(er)",
"RetryAfter:Minutes": "{0} minut(er)",
"RetryAfter:MinutesAndSeconds": "{0} minut(er) och {1} sekund(er)",
- "RetryAfter:Seconds": "{0} sekund(er)"
+ "RetryAfter:Seconds": "{0} sekund(er)",
+ "Volo.Abp.OperationRateLimiting:010002": "Hastighetsgränsen för operationen har överskridits. Denna förfrågan är permanent nekad."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/tr.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/tr.json
index 3ce04aa915..0480003f9c 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/tr.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/tr.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} saat ve {1} dakika",
"RetryAfter:Minutes": "{0} dakika",
"RetryAfter:MinutesAndSeconds": "{0} dakika ve {1} saniye",
- "RetryAfter:Seconds": "{0} saniye"
+ "RetryAfter:Seconds": "{0} saniye",
+ "Volo.Abp.OperationRateLimiting:010002": "İşlem hızı sınırı aşıldı. Bu istek kalıcı olarak reddedildi."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/vi.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/vi.json
index 6b0ee47927..53059f819c 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/vi.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/vi.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} giờ và {1} phút",
"RetryAfter:Minutes": "{0} phút",
"RetryAfter:MinutesAndSeconds": "{0} phút và {1} giây",
- "RetryAfter:Seconds": "{0} giây"
+ "RetryAfter:Seconds": "{0} giây",
+ "Volo.Abp.OperationRateLimiting:010002": "Vượt quá giới hạn tần suất thao tác. Yêu cầu này bị từ chối vĩnh viễn."
}
}
diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/zh-Hans.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/zh-Hans.json
index 6472587357..632d0e438f 100644
--- a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/zh-Hans.json
+++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/zh-Hans.json
@@ -12,6 +12,7 @@
"RetryAfter:HoursAndMinutes": "{0} 小时 {1} 分钟",
"RetryAfter:Minutes": "{0} 分钟",
"RetryAfter:MinutesAndSeconds": "{0} 分钟 {1} 秒",
- "RetryAfter:Seconds": "{0} 秒"
+ "RetryAfter:Seconds": "{0} 秒",
+ "Volo.Abp.OperationRateLimiting:010002": "操作频率超出限制。此请求已被永久拒绝。"
}
}
diff --git a/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingException_Tests.cs b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingException_Tests.cs
index bf20e1f6a4..9d88c5e57d 100644
--- a/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingException_Tests.cs
+++ b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingException_Tests.cs
@@ -24,14 +24,15 @@ public class AbpOperationRateLimitingException_Tests
}
[Fact]
- public void Should_Set_Default_ErrorCode()
+ public void Should_Use_ExceedLimit_Code_When_RetryAfter_Is_Set()
{
var result = new OperationRateLimitingResult
{
IsAllowed = false,
MaxCount = 3,
CurrentCount = 3,
- RemainingCount = 0
+ RemainingCount = 0,
+ RetryAfter = TimeSpan.FromMinutes(5)
};
var exception = new AbpOperationRateLimitingException("TestPolicy", result);
@@ -39,6 +40,23 @@ public class AbpOperationRateLimitingException_Tests
exception.Code.ShouldBe(AbpOperationRateLimitingErrorCodes.ExceedLimit);
}
+ [Fact]
+ public void Should_Use_ExceedLimitPermanently_Code_When_RetryAfter_Is_Null()
+ {
+ var result = new OperationRateLimitingResult
+ {
+ IsAllowed = false,
+ MaxCount = 0,
+ CurrentCount = 0,
+ RemainingCount = 0,
+ RetryAfter = null
+ };
+
+ var exception = new AbpOperationRateLimitingException("TestPolicy", result);
+
+ exception.Code.ShouldBe(AbpOperationRateLimitingErrorCodes.ExceedLimitPermanently);
+ }
+
[Fact]
public void Should_Set_Custom_ErrorCode()
{
diff --git a/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingChecker_Tests.cs b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingChecker_Tests.cs
index 08a605c894..fd3d9f4214 100644
--- a/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingChecker_Tests.cs
+++ b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingChecker_Tests.cs
@@ -655,6 +655,7 @@ public class OperationRateLimitingChecker_Tests : OperationRateLimitingTestBase
exception.Result.MaxCount.ShouldBe(0);
exception.Result.RetryAfter.ShouldBeNull();
exception.HttpStatusCode.ShouldBe(429);
+ exception.Code.ShouldBe(AbpOperationRateLimitingErrorCodes.ExceedLimitPermanently);
}
[Fact]