WhiskeySockets / Baileys

Lightweight full-featured typescript/javascript WhatsApp Web API
https://baileys.whiskeysockets.io/
MIT License
4.01k stars 1.36k forks source link

[BUG] Rate-Overlimit and Unexpected Error in 'Handling Bad ACK' #1061

Open CSFelix opened 1 month ago

CSFelix commented 1 month ago

Description

When sending or receiving a bunch of group messages in a short period of time, the following error is triggered:

{
  "level":50,"time":"2024-09-23T17:47:10.712Z","pid":8348,"hostname":"hostname","err":{"type":"Error","message":"rate-overlimit","stack":"Error: rate-overlimit
    at assertNodeErrorFree (@whiskeysockets\\baileys\\lib\\WABinary\\generic-utils.js:56:15)
    at query (@whiskeysockets\\baileys\\lib\\Socket\\socket.js:145:48)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async groupMetadata (@whiskeysockets\\baileys\\lib\\Socket\\groups.js:22:24)
    at async @whiskeysockets\\baileys\\lib\\Socket\\messages-send.js:323:41
    at async Promise.all (index 0)
    at async @whiskeysockets\\baileys\\lib\\Socket\\messages-send.js:316:51
    at async Object.transaction (@whiskeysockets\\baileys\\lib\\Utils\\auth-utils.js:136:26)
    at async relayMessage (@whiskeysockets\\baileys\\lib\\Socket\\messages-send.js:306:9)
    at async handleBadAck (@whiskeysockets\\baileys\\lib\\Socket\\messages-recv.js:775:17)",
  "data":429,"isBoom":true,"isServer":true,"output":{"statusCode":500,"payload":{"statusCode":500,"error":"Internal Server 
  Error","message":"An internal server error occurred"},"headers":{}}},"msg":"unexpected error in 'handling bad ack'"
}

Reproducibility

  1. Create a new connection
  2. Send a bunch of messages in a group
  3. Keep doing it for some seconds and the error is triggered

Expected behavior

All the messages should be sent/received without triggering errors.


Environment

Yes, but the issue also happens on localhost.
makeWASocket({
  logger: loggerBaileys,
  printQRInTerminal: false,
  auth: state as AuthenticationState,
  generateHighQualityLinkPreview: false,
  syncFullHistory: true,
  markOnlineOnConnect: true,
  patchMessageBeforeSending: message => {
    const requiresPatch = !!(
      message.buttonsMessage || message.listMessage
    );
    if (requiresPatch) {
      message = {
        viewOnceMessage: {
          message: {
            messageContextInfo: {
              deviceListMetadataVersion: 2,
              deviceListMetadata: {}
            },
            ...message
          }
        }
      };
    }
    return message;
  },
  getMessage
});
Yes, but the issue also happens on localhost with a single client.
Nope
Skidy89 commented 1 month ago

add cache and no request every time groupMetadata

CSFelix commented 1 month ago

add cache and no request every time groupMetadata

Even though not using groupMetadata, the issue remains

CSFelix commented 1 month ago

I dived into the problem and I found out where the error is happening:

  1. ./Socket/messages-send file - when I send messages to groups, it calls relayMessage function that, consequently, calls await groupMetadata(jid) function when the chat is a group. So, when sending a bunch of messages in a short period of time in groups, relayMessage()-groupMetadata() is called multiple times over the short period and then rate-overlimit is triggered;

  2. ./Socket/group file - getting into groupMetadata(), I found out the problem is into groupQuery function that calls query function

  3. ./Socket/socket file - into query(), waitForMessage function is called, assigning the return into result variable like the code below:

const wait = waitForMessage(msgId, timeoutMs);
await sendNode(node);
const result = await wait;

When the error does not occur, result is the message object itself. When the error occurs, result is the error object like below:

{"tag":"iq","attrs":{"from":"<jid>@g.us","type":"error","id":"<four_digits_number>.<five_digits_number>-<two_digits_number>"},"content":[{"tag":"error","attrs":{"code":"429","text":"rate-overlimit"}}]} 
  1. In the end, result is passed as parameter to WABinary_1.assertNodeErrorFree function that throws a Boom Error when error is the value of type key into result.content

I found out where the error is happening, but I didn't find out the cause 😭

vinikjkkj commented 1 month ago

add cache and no request every time groupMetadata

Even though not using groupMetadata, the issue remains

baileys fetch groupMetadata to send message, even you not fetch, that's why you should use caching, in socket have cachedGroupMetadata argument