diff --git a/README.md b/README.md index 33e0c43..238a6fa 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@ send to the core — inheriting rotation, proxy, retry, and result for free. ## Install ``` -aiowebhooks @ git+ssh://git@git.rethinkstudios.io/rethink-public/aiowebhooks.git@v0.1.2 +aiowebhooks @ git+ssh://git@git.rethinkstudios.io/rethink-public/aiowebhooks.git@v0.1.3 # discord embeds / identity helpers need the extra: -aiowebhooks[discord] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aiowebhooks.git@v0.1.2 +aiowebhooks[discord] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aiowebhooks.git@v0.1.3 ``` The base pulls `aiohttp` and `commons` (for the retry/backoff engine). Only diff --git a/pyproject.toml b/pyproject.toml index 7f4b64a..ff1dedf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "aiowebhooks" -version = "0.1.2" +version = "0.1.3" description = "async webhook sender (aiohttp) with round-robin urls, retry, and proxy rotation; optional discord.py embeds" requires-python = ">=3.10" dependencies = [ diff --git a/src/aiowebhooks/__init__.py b/src/aiowebhooks/__init__.py index c212c69..623b77e 100644 --- a/src/aiowebhooks/__init__.py +++ b/src/aiowebhooks/__init__.py @@ -21,4 +21,4 @@ from .sender import Webhook __all__ = ["Webhook", "WebhookResult", "WebhookError", "NoUrlsError"] -__version__ = "0.1.2" +__version__ = "0.1.3" diff --git a/src/aiowebhooks/sender.py b/src/aiowebhooks/sender.py index ee8f81b..fb3ebd6 100644 --- a/src/aiowebhooks/sender.py +++ b/src/aiowebhooks/sender.py @@ -201,10 +201,16 @@ class Webhook: error=f"http {status}", response=body, proxy=last_proxy, ) - wait = self._retry_after(status, resp.headers, body) - if wait is not None: - log.warning("webhook 429 on %s; honoring retry_after %.3fs", url, wait) - await asyncio.sleep(wait) + if status == 429: + # every 429 is retryable; honor an explicit retry_after by + # sleeping it, but a 429 with no parseable wait (edge/Cloudflare/ + # generic webhook) still retries under aretry's backoff + cap + wait = self._retry_after(status, resp.headers, body) + if wait is not None: + log.warning("webhook 429 on %s; honoring retry_after %.3fs", url, wait) + await asyncio.sleep(wait) + else: + log.warning("webhook 429 on %s; no retry_after, backing off", url) raise _Retryable(result) if status >= 500: raise _Retryable(result)