mirror of
https://github.com/AsamK/signal-cli.git
synced 2026-06-09 16:50:19 +00:00
* Surface retry-after seconds for plain rate-limit failures libsignal-service's RateLimitException exposes retryAfterMilliseconds for HTTP 413 responses, but signal-cli only forwarded retry-after for ProofRequired (428) failures. Clients had no signal for when it was safe to retry plain rate-limited sends, so every failed retry potentially extended the server-side window. SendMessageResult now carries an optional rateLimitRetryAfterSeconds, populated from the upstream Optional<Long>. JsonSendMessageResult exposes it for RATE_LIMIT_FAILURE type. Text output includes the window when known. Aggregate RateLimitErrorException now carries the real nextAttemptTimestamp (was hardcoded to 0). Closes #1996. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Address review: include proof-required retry-after and ceiling-round millis Codex adversarial review flagged two issues in the phase 1 retry-after plumbing: * Aggregate retry-after ignored proof-required failures. Because isRateLimitFailure is true for proof-required cases but rateLimitRetryAfterSeconds was only populated from plain 413s, an all-proof-required batch (or a mixed batch where the proof-required delay was longer) could flow into outputResult() and produce a RateLimitException(0), telling callers to retry immediately. * Millisecond Retry-After values were truncated by integer division, so 1..999ms became 0 and non-second-aligned values lost up to 999ms. A retry suggested from the floored value can land before the server's real deadline and re-trigger the limit. SendMessageResult.from(...) now populates rateLimitRetryAfterSeconds from either the proof-required seconds or the plain rate-limit ms (converted via ceiling division), giving maxRateLimitRetryAfterSeconds a single source of truth. JsonSendMessageResult.from(...) reads the unified field. New millisToCeilingSeconds helper plus boundary test. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Preserve source compat and document retry-after field change Add a non-canonical 8-arg SendMessageResult constructor that delegates to the canonical form with null retry-after. This keeps source compatibility for any downstream code that constructs the record directly (tests, mocks) without changing the canonical shape. Records permit additional constructors alongside the canonical one. Document the retryAfterSeconds meaning change in the CHANGELOG. The field was previously populated only for proof-required failures; it is now populated whenever the server sends a Retry-After header. The canonical proof-required discriminator is still token != null. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>