]> nmode's Git Repositories - signal-cli/commitdiff
Handle rate limit exception correctly when querying usernames
authorAsamK <asamk@gmx.de>
Sat, 12 Jul 2025 09:03:28 +0000 (11:03 +0200)
committerAsamK <asamk@gmx.de>
Sat, 12 Jul 2025 09:03:28 +0000 (11:03 +0200)
Fixes #1797

graalvm-config-dir/jni-config.json
lib/src/main/java/org/asamk/signal/manager/Manager.java
lib/src/main/java/org/asamk/signal/manager/helper/RecipientHelper.java
lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java
src/main/java/org/asamk/signal/commands/GetUserStatusCommand.java

index 23a2160c6b6f26357e74dd713c0f9ee977f5f633..523a6c0363b2368241e4c34b2e52cca45a5381b3 100644 (file)
@@ -58,7 +58,7 @@
 },
 {
   "name":"java.lang.Throwable",
 },
 {
   "name":"java.lang.Throwable",
-  "methods":[{"name":"getMessage","parameterTypes":[] }, {"name":"toString","parameterTypes":[] }]
+  "methods":[{"name":"getMessage","parameterTypes":[] }, {"name":"setStackTrace","parameterTypes":["java.lang.StackTraceElement[]"] }, {"name":"toString","parameterTypes":[] }]
 },
 {
   "name":"java.lang.UnsatisfiedLinkError",
 },
 {
   "name":"java.lang.UnsatisfiedLinkError",
   "name":"org.signal.libsignal.net.NetworkException",
   "methods":[{"name":"<init>","parameterTypes":["java.lang.String"] }]
 },
   "name":"org.signal.libsignal.net.NetworkException",
   "methods":[{"name":"<init>","parameterTypes":["java.lang.String"] }]
 },
+{
+  "name":"org.signal.libsignal.net.RetryLaterException",
+  "methods":[{"name":"<init>","parameterTypes":["long"] }]
+},
 {
   "name":"org.signal.libsignal.protocol.DuplicateMessageException",
   "methods":[{"name":"<init>","parameterTypes":["java.lang.String"] }]
 {
   "name":"org.signal.libsignal.protocol.DuplicateMessageException",
   "methods":[{"name":"<init>","parameterTypes":["java.lang.String"] }]
index 238084e72f3c0a876d2e90df7ffcb25a2162955f..ccb661e19ba2c8f88c87b95e613296f02ac052a4 100644 (file)
@@ -96,7 +96,7 @@ public interface Manager extends Closeable {
      */
     Map<String, UserStatus> getUserStatus(Set<String> numbers) throws IOException, RateLimitException;
 
      */
     Map<String, UserStatus> getUserStatus(Set<String> numbers) throws IOException, RateLimitException;
 
-    Map<String, UsernameStatus> getUsernameStatus(Set<String> usernames);
+    Map<String, UsernameStatus> getUsernameStatus(Set<String> usernames) throws IOException;
 
     void updateAccountAttributes(
             String deviceName,
 
     void updateAccountAttributes(
             String deviceName,
index ecb85254743f6ea97da58282e78887c13f3f6125..a73bb741469152cd7ec12882fb289fa92caf3d03 100644 (file)
@@ -17,6 +17,7 @@ import org.whispersystems.signalservice.api.push.ServiceId.PNI;
 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
 import org.whispersystems.signalservice.api.push.exceptions.CdsiInvalidArgumentException;
 import org.whispersystems.signalservice.api.push.exceptions.CdsiInvalidTokenException;
 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
 import org.whispersystems.signalservice.api.push.exceptions.CdsiInvalidArgumentException;
 import org.whispersystems.signalservice.api.push.exceptions.CdsiInvalidTokenException;
+import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException;
 
 import java.io.IOException;
 import java.util.Collection;
 
 import java.io.IOException;
 import java.util.Collection;
@@ -68,7 +69,7 @@ public class RecipientHelper {
                 .toSignalServiceAddress();
     }
 
                 .toSignalServiceAddress();
     }
 
-    public Set<RecipientId> resolveRecipients(Collection<RecipientIdentifier.Single> recipients) throws UnregisteredRecipientException {
+    public Set<RecipientId> resolveRecipients(Collection<RecipientIdentifier.Single> recipients) throws UnregisteredRecipientException, IOException {
         final var recipientIds = new HashSet<RecipientId>(recipients.size());
         for (var number : recipients) {
             final var recipientId = resolveRecipient(number);
         final var recipientIds = new HashSet<RecipientId>(recipients.size());
         for (var number : recipients) {
             final var recipientId = resolveRecipient(number);
@@ -91,7 +92,11 @@ public class RecipientHelper {
                 }
             });
         } else if (recipient instanceof RecipientIdentifier.Username(String username)) {
                 }
             });
         } else if (recipient instanceof RecipientIdentifier.Username(String username)) {
-            return resolveRecipientByUsernameOrLink(username, false);
+            try {
+                return resolveRecipientByUsernameOrLink(username, false);
+            } catch (Exception e) {
+                return null;
+            }
         }
         throw new AssertionError("Unexpected RecipientIdentifier: " + recipient);
     }
         }
         throw new AssertionError("Unexpected RecipientIdentifier: " + recipient);
     }
@@ -99,7 +104,7 @@ public class RecipientHelper {
     public RecipientId resolveRecipientByUsernameOrLink(
             String username,
             boolean forceRefresh
     public RecipientId resolveRecipientByUsernameOrLink(
             String username,
             boolean forceRefresh
-    ) throws UnregisteredRecipientException {
+    ) throws UnregisteredRecipientException, IOException {
         final Username finalUsername;
         try {
             finalUsername = getUsernameFromUsernameOrLink(username);
         final Username finalUsername;
         try {
             finalUsername = getUsernameFromUsernameOrLink(username);
@@ -110,11 +115,15 @@ public class RecipientHelper {
             try {
                 final var aci = handleResponseException(dependencies.getUsernameApi().getAciByUsername(finalUsername));
                 return account.getRecipientStore().resolveRecipientTrusted(aci, finalUsername.getUsername());
             try {
                 final var aci = handleResponseException(dependencies.getUsernameApi().getAciByUsername(finalUsername));
                 return account.getRecipientStore().resolveRecipientTrusted(aci, finalUsername.getUsername());
-            } catch (IOException e) {
-                throw new UnregisteredRecipientException(new org.asamk.signal.manager.api.RecipientAddress(null,
-                        null,
-                        null,
-                        username));
+            } catch (NonSuccessfulResponseCodeException e) {
+                if (e.code == 404) {
+                    throw new UnregisteredRecipientException(new org.asamk.signal.manager.api.RecipientAddress(null,
+                            null,
+                            null,
+                            username));
+                }
+                logger.debug("Failed to get uuid for username: {}", username, e);
+                throw e;
             }
         }
         return account.getRecipientStore().resolveRecipientByUsername(finalUsername.getUsername(), () -> {
             }
         }
         return account.getRecipientStore().resolveRecipientByUsername(finalUsername.getUsername(), () -> {
index ffb74de26a2b0e32d3b11b4b80d09b169d3b8461..eb672d24f9ef130b71cb457426fdfcdc42f85a23 100644 (file)
@@ -285,7 +285,7 @@ public class ManagerImpl implements Manager {
     }
 
     @Override
     }
 
     @Override
-    public Map<String, UsernameStatus> getUsernameStatus(Set<String> usernames) {
+    public Map<String, UsernameStatus> getUsernameStatus(Set<String> usernames) throws IOException {
         final var registeredUsers = new HashMap<String, RecipientAddress>();
         for (final var username : usernames) {
             try {
         final var registeredUsers = new HashMap<String, RecipientAddress>();
         for (final var username : usernames) {
             try {
index e3d36d8538b01b584927724d785a145fcd99a301..eab4155c710beebd7536a2af53edacea91fa601c 100644 (file)
@@ -64,9 +64,16 @@ public class GetUserStatusCommand implements JsonRpcLocalCommand {
         }
 
         final var usernames = ns.<String>getList("username");
         }
 
         final var usernames = ns.<String>getList("username");
-        final var registeredUsernames = usernames == null
-                ? Map.<String, UsernameStatus>of()
-                : m.getUsernameStatus(new HashSet<>(usernames));
+        final Map<String, UsernameStatus> registeredUsernames;
+        try {
+            registeredUsernames = usernames == null ? Map.of() : m.getUsernameStatus(new HashSet<>(usernames));
+        } catch (IOException e) {
+            throw new IOErrorException("Unable to check if users are registered: "
+                    + e.getMessage()
+                    + " ("
+                    + e.getClass().getSimpleName()
+                    + ")", e);
+        }
 
         // Output
         switch (outputWriter) {
 
         // Output
         switch (outputWriter) {