Commit Graph

8 Commits

Author SHA1 Message Date
ef20bc51f0 fix: never-raises net widened to unexpected exceptions; changelog/429 docs (v0.1.4)
M-2: _attempt caught only (aiohttp.ClientError, asyncio.TimeoutError); an unexpected
error escaping the attempt (closed injected session -> RuntimeError, malformed proxy url
-> ValueError) propagated out of send(), breaking the documented 'never raises on a send
failure' contract. add an outer catch-all in _send_loop converting any such exception to a
falsy WebhookResult(ok=False), logged at warning with exc_info.

aiowebhooks-F3: README 429 section + changelog were stale vs the v0.1.3 'retry any 429'
fix; added the no-parseable-wait-still-retries wording and v0.1.3/v0.1.4 changelog entries.

verified by execution: closed-session (RuntimeError) and bad-proxy (ValueError) controls
both fire and now return ok=False instead of raising.

Signed-off-by: disqualifier <dev@disqualifier.me>
2026-06-29 20:47:30 -04:00
28bad7fc7f docs: pin install line to release, note unpinned-latest option
Signed-off-by: disqualifier <dev@disqualifier.me>
2026-06-29 18:13:35 -04:00
1d3418a4be docs: show unpinned install line; note tag-pinning for reproducibility
Signed-off-by: disqualifier <dev@disqualifier.me>
2026-06-29 18:07:20 -04:00
f3d2561bf9 fix: retry any 429, not just those with a parseable retry_after (v0.1.3)
treat every status==429 as retryable: sleep only when retry_after parses, but raise
_Retryable either way so aretry's backoff + max_retries cap engages. previously a 429
with no body retry_after and no Retry-After header (edge/Cloudflare/generic webhook)
returned a terminal ok=False with no retry, contradicting the documented retry-on-429.

Signed-off-by: disqualifier <dev@disqualifier.me>
2026-06-29 17:09:30 -04:00
cd93e4f44f fix: per-call attempt counter so concurrent sends don't corrupt attempts
the attempt count used instance state (self._attempt_no), reset in _send_loop and incremented in _attempt; two concurrent send() calls on one Webhook interleaved, corrupting each other's WebhookResult.attempts. it is now a per-call mutable cell created in _send_loop and threaded into _attempt. verified under load: 400 concurrent sends, zero corrupted counts.

Signed-off-by: disqualifier <dev@disqualifier.me>
2026-06-28 17:46:20 -04:00
bcf1f5511c fix: _proxy_string emits no stray colons for a portless proxy
a portless proxy url produced host::user:pass / host: (extra colons), breaking the identity match against the provider pool. the port colon is now omitted when there is no port, mirroring aioproxies' canonical key.

Signed-off-by: disqualifier <dev@disqualifier.me>
2026-06-28 17:18:28 -04:00
aec0a5cc2b fix: remove dead clock param; pin commons v0.2.1 (v0.1.2)
the clock= constructor param was stored (self._clock) but never read — the 429
retry_after wait uses asyncio.sleep directly. it was dead code, and the CLAUDE.md
wrongly claimed it made 429 timing test-controllable. remove the param + the unused
time import, and correct the doc (tests patch commons.retry's sleep + sender.asyncio
.sleep, not a clock seam). bump the commons pin to v0.2.1 (retry attempts floor).

verified: clock param gone, constructs fine, 18/18 fix harness intact.
Signed-off-by: disqualifier <dev@disqualifier.me>
2026-06-28 16:16:13 -04:00
3f164abf84 init: async webhook sender (aiohttp) with retry & proxy rotation, optional discord embeds
Signed-off-by: disqualifier <dev@disqualifier.me>
2026-06-25 14:50:05 -04:00