Retry ETTN creation on Nova Poshta rate limit instead of failing
Checkbox relays Nova Poshta's "To many requests" (20000401501) as a 4xx third_party.generic error, not a 429, so bursts of receipt requests ended up as failed receipts. Such responses are now CheckboxRateLimitedError: the receipt stays pending and the worker job is retried with arq.Retry after the "Try again after N seconds" delay plus backoff. NP timeouts relayed the same way are treated as unavailable (unknown outcome). The HTTP client also sends Checkbox requests one at a time with a CHECKBOX_MIN_REQUEST_INTERVAL_MS pause and signs the cashier in once for concurrent jobs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,18 @@ class CheckboxUnavailableError(CheckboxError):
|
||||
"""Сеть, таймаут или 5xx — исход запроса неизвестен, можно повторить."""
|
||||
|
||||
|
||||
class CheckboxRateLimitedError(CheckboxUnavailableError):
|
||||
"""Лимит частоты запросов (Checkbox 429 или «To many requests» от Новой Почты).
|
||||
|
||||
В отличие от прочих `CheckboxUnavailableError` исход известен — запрос отклонён,
|
||||
повторять можно не раньше чем через `retry_after` секунд.
|
||||
"""
|
||||
|
||||
def __init__(self, message: str, retry_after: float) -> None:
|
||||
super().__init__(message)
|
||||
self.retry_after = retry_after
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class CheckboxCredentials:
|
||||
"""Расшифрованные доступы одной кассы. Живут только в памяти."""
|
||||
|
||||
Reference in New Issue
Block a user