diff --git a/CHANGELOG.md b/CHANGELOG.md index af02c08d..44478806 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Changed + +- Send message results now surface server-advised retry time for plain rate-limit (HTTP 413) failures, not only for proof-required challenges. The `retryAfterSeconds` field in JSON-RPC `SendMessageResult` is populated whenever the server sends a `Retry-After` header. The canonical way to distinguish proof-required failures remains `token != null`. Text output includes "retry after N seconds" when known. + ## [0.14.2] - 2026-04-04 ### Added diff --git a/lib/src/main/java/org/asamk/signal/manager/api/SendMessageResult.java b/lib/src/main/java/org/asamk/signal/manager/api/SendMessageResult.java index 081a7873..82b83aa9 100644 --- a/lib/src/main/java/org/asamk/signal/manager/api/SendMessageResult.java +++ b/lib/src/main/java/org/asamk/signal/manager/api/SendMessageResult.java @@ -15,6 +15,32 @@ public record SendMessageResult( Long rateLimitRetryAfterSeconds ) { + /** + * Source-compatible constructor for callers built against the pre-retry-after record shape. + * Delegates to the canonical constructor with a null retry-after, which is the correct value + * for any result not produced by {@link #from}. + */ + public SendMessageResult( + RecipientAddress address, + boolean isSuccess, + boolean isNetworkFailure, + boolean isUnregisteredFailure, + boolean isIdentityFailure, + boolean isRateLimitFailure, + ProofRequiredException proofRequiredFailure, + boolean isInvalidPreKeyFailure + ) { + this(address, + isSuccess, + isNetworkFailure, + isUnregisteredFailure, + isIdentityFailure, + isRateLimitFailure, + proofRequiredFailure, + isInvalidPreKeyFailure, + null); + } + public static SendMessageResult unregisteredFailure(RecipientAddress address) { return new SendMessageResult(address, false, false, true, false, false, null, false, null); } diff --git a/lib/src/test/java/org/asamk/signal/manager/api/SendMessageResultTest.java b/lib/src/test/java/org/asamk/signal/manager/api/SendMessageResultTest.java index fd5b2b93..b4a4bf4e 100644 --- a/lib/src/test/java/org/asamk/signal/manager/api/SendMessageResultTest.java +++ b/lib/src/test/java/org/asamk/signal/manager/api/SendMessageResultTest.java @@ -3,6 +3,7 @@ package org.asamk.signal.manager.api; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; class SendMessageResultTest { @@ -21,4 +22,17 @@ class SendMessageResultTest { assertEquals(2L, SendMessageResult.millisToCeilingSeconds(1500L)); assertEquals(60L, SendMessageResult.millisToCeilingSeconds(60_000L)); } + + /** + * Source-compat: callers built against the pre-retry-after record shape use the 8-arg + * constructor. It must continue to compile and produce a record with a null retry-after. + */ + @Test + @SuppressWarnings("deprecation") + void legacyEightArgConstructorPreservesSourceCompat() { + var result = new SendMessageResult(new RecipientAddress(null, null, "+15551234567", null), + true, false, false, false, false, null, false); + + assertNull(result.rateLimitRetryAfterSeconds()); + } }