* refactor(channels): generalize channel retry runner and retry-after parsing; drop dead configured-state probes
* fix(channels): align retry and metadata contracts
* fix(discord): stop retrying non-idempotent sends on post-connect-ambiguous errors
Discord's outbound retry runner treated every transient transport error as
retryable, including ECONNRESET, ETIMEDOUT, AbortError, and the undici
headers/body/socket timeouts. Those errors can fire after Discord has already
received and created the message but before the client reads the response, so
replaying the non-idempotent createChannelMessage POST delivers the same
message twice while reporting success.
Add a pre-connect-only classifier (isRetryableDiscordPreConnectError) covering
errors that provably never reached Discord (DNS/connect refused/connect
timeout) plus rate-limit rejections, mirroring the Telegram send-path
carve-out. The retry runner now accepts a per-call nonIdempotent option; the
message-create and thread-create call sites opt in so ambiguous post-connect
errors surface to the caller instead of double-sending. Idempotent REST calls
(reactions, edits, DM-channel lookup, uploads) keep the broader transient set.
* fix(discord): retry nonce-enforced message creates
* fix(discord): scope create retries by endpoint
* fix(discord): stabilize sticker and poll create nonce across retries
* fix(discord): tighten create retry safety
* fix(discord): preserve nonce-safe retries
* fix(discord): scope nonce fields to message creates
* test(discord): cover nonce-safe direct sends
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(discord): drain queued outbound deliveries after gateway reconnect (#56610)
Discord sends that failed while the gateway websocket was reconnecting
(close codes 1005/1006) stayed stuck in the outbound delivery queue and
were silently dropped. Classify sends that fail while the registered
gateway is disconnected as retryable, and drain pending discord queue
entries when the gateway reconnects, matching the WhatsApp/Telegram
reconnect drains.
* fix(discord): harden reconnect recovery
Co-authored-by: tiffanychum <71036662+tiffanychum@users.noreply.github.com>
* refactor(discord): remove unsafe reconnect replay
* fix(discord): bound reconnect retry per request
Co-authored-by: tiffanychum <71036662+tiffanychum@users.noreply.github.com>
* chore(changelog): leave reconnect fix to release flow
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>