WoJo
WoJo

Reputation: 516

How to .catch error before continuing with code?

I have a command which sends a message to every user in the guild. Of course there is a possibility where users have DM's turned off. I want to count those users (And send a message to the channel with the amount of users having it disabled) by using .catch.

My problem is, the .catch block performs itself after the rest of the command (The part where it sends a message to the channel) In the .catch block I add 1 to a variable, every time it gives me the error. In the channel message, I send the variable. Obviously, the variable will be 0 since it sends the message before it runs the .catch block.

How do I send the message with the amount of users that have it turned off, after the .catch block?

This is my code:

var text = args.join(' ')
message.guild.members.forEach(member => {
     member.send(text).catch(() => {
          console.log("Can't send DM to this user!")
          faultyusers++
     });
});
console.log(faultyusers);
message.channel.send("Successfully sent message to all members in the server. (Warning: **" + faultyusers + "** users might have not received the message because of their settings.)")

(faultyusers is always 0 when I run this.)

Upvotes: 1

Views: 102

Answers (1)

Max
Max

Reputation: 4739

Each member.send() is asynchronous. So for this you need to create a Promise for each member.send() call. After that, you run all the promises and when they all resolve, you are left with array of results, from which you can count amount of users that did not receive the message

// this function returns promise that will
// resolve with { success: true } or { success: false }
// depending on whether or not the user received the message (member.send() failed)
const sendMessageAndGetResult = (text, member) =>
    member
      .send(text)
      .then(() => ({ success: true }))
      .catch(() => ({ success: false }))

const sendMessages = async (text) => {
  // create one such promise for each user in guild
  const promises = message.guild.members.map(member => sendMessageAndGetResult(text, member))
  // wait until all promises are resolved
  // allResults will be an looking like this [{ success: true }, { success: false }, ...]
  const allResults = await Promise.all(promises)
  // count users that did not receive message
  const faultyUsersCount = allResults.filter(result => !result.success).length
  console.log(faultyUsersCount)
  message.channel.send("Successfully sent message to all members in the server. (Warning: **" + faultyUsersCount + "** users might have not received the message because of their settings.)")
}

// usage
sendMessages('hello')

Upvotes: 3

Related Questions