【问题标题】:How to fix 'UnhandledPromiseRejectionWarning' in console如何在控制台中修复“UnhandledPromiseRejectionWarning”
【发布时间】:2019-09-26 03:53:24
【问题描述】:

我有一个不和谐的机器人,我最近实施了一个货币系统,但是,每次有人说一条消息时,我都会在控制台中收到这个“UnhandledPromiseRejectionWarning”警告。

我尝试过使用 catch,但这似乎不起作用。

这是完整的错误:

(node:4633) UnhandledPromiseRejectionWarning: SequelizeUniqueConstraintError: Validation error
    at Query.formatError (/Users/**censored**/node_modules/sequelize/lib/dialects/sqlite/query.js:413:16)
    at Query._handleQueryResponse (/Users/**censored**/node_modules/sequelize/lib/dialects/sqlite/query.js:73:18)
    at Statement.afterExecute (/Users/**censored**/node_modules/sequelize/lib/dialects/sqlite/query.js:247:31)
    at Statement.replacement (/Users/**censored**/node_modules/sqlite3/lib/trace.js:19:31)
(node:4633) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 29)

JavaScript 代码:

client.once('ready', async() => {
    const target = message.mentions.users.first() || message.author;
    return message.channel.send(`${target.tag} has ${currency.getBalance(target.id)}????`);
});

client.on('message', async message => {
    if (message.author.bot) return;
    currency.add(message.author.id, 1);

    if (!message.content.startsWith(PREFIX)) return;
    const input = message.content.slice(PREFIX.length).trim();
    if (!input.length) return;
    const [, command, commandArgs] = input.match(/(\w+)\s*([\s\S]*)/);

    if (command === 'balance') {
        const target = message.mentions.users.first() || message.author;
        return message.channel.send(`${target.tag} has ${currency.getBalance(target.id)}????`);
    } else if (command === 'inventory') {
        const target = message.mentions.users.first() || message.author;
        const user = await Users.findByPrimary(target.id);
        const items = await user.getItems();

        if (!items.length) return message.channel.send(`${target.tag} has nothing!`);
        return message.channel.send(`${target.tag} currently has ${items.map(i => `${i.amount} ${i.item.name}`).join(', ')}`);
    } else if (command === 'transfer') {
        const currentAmount = currency.getBalance(message.author.id);
        const transferAmount = commandArgs.split(/ +/g).find(arg => !/<@!?\d+>/g.test(arg));
        const transferTarget = message.mentions.users.first();

        if (!transferAmount || isNaN(transferAmount)) return message.channel.send(`Sorry ${message.author}, that's an invalid amount.`);
        if (transferAmount > currentAmount) return message.channel.send(`Sorry ${message.author}, you only have ${currentAmount}.`);
        if (transferAmount <= 0) return message.channel.send(`Please enter an amount greater than zero, ${message.author}.`);

        currency.add(message.author.id, -transferAmount);
        currency.add(transferTarget.id, transferAmount);

        return message.channel.send(`Successfully transferred ${transferAmount}???? to ${transferTarget.tag}. Your current balance is ${currency.getBalance(message.author.id)}????`);
    } else if (command === 'buy') {
        const item = await CurrencyShop.findOne({
            where: {
                name: {
                    [Op.like]: commandArgs
                }
            }
        });
        if (!item) return message.channel.send(`That item doesn't exist.`);
        if (item.cost > currency.getBalance(message.author.id)) {
            return message.channel.send(`You currently have ${currency.getBalance(message.author.id)}, but the ${item.name} costs ${item.cost}!`);
        }

        const user = await Users.findByPrimary(message.author.id);
        currency.add(message.author.id, -item.cost);
        await user.addItem(item);

        message.channel.send(`You've bought: ${item.name}.`);
    } else if (command === 'shop') {
        const items = await CurrencyShop.findAll();
        return message.channel.send(items.map(item => `${item.name}: ${item.cost}????`).join('\n'), {
            code: true
        });
    } else if (command === 'leaderboard') {
        return message.channel.send(
            currency.sort((a, b) => b.balance - a.balance)
            .filter(user => client.users.has(user.user_id))
            .first(10)
            .map((user, position) => `(${position + 1}) ${(client.users.get(user.user_id).tag)}: ${user.balance}????`)
            .join('\n'), {
                code: true
            }
        );
    }
}); 

【问题讨论】:

  • 第一个你不需要准备好的处理程序中的异步的东西。

标签: javascript discord.js nodemon


【解决方案1】:

发生了什么事?

当使用返回 Promise 的方法时,你不能总是假设一切都会完美运行。有时,某些事情可能会失败,结果将是一个被拒绝的承诺。未处理时,会发出 unhandledPromiseRejectionWarning,就像您遇到的那样。

从错误来看,sequelize 查询中的某些内容似乎出了问题,特别是在验证方面。

解决办法?

始终确保您正确处理任何拒绝的可能性。使用try...catch 语句或catch() 方法。

例子:

try {
  const items = await CurrencyShop.findAll();
  message.channel.send(...);
} catch(err) {                                 // Even if only one promise is rejected,
  console.error(err);                          // the code inside the 'catch' is still
}                                              // executed.
message.channel.send('hi there')
  .catch(err => console.error(err));

文档

【讨论】:

    【解决方案2】:

    我可以看到许多对send 的调用返回承诺但不是正确的句柄。

    您也不能假设client 正确捕获了您从处理程序返回的承诺的错误。 client.on 肯定不会期待任何回报。

    我建议您将处理程序包装在一个函数中,该函数将执行适当的 try catch 并且不返回任何内容。

    【讨论】:

      猜你喜欢
      • 2019-12-15
      • 2019-12-16
      • 1970-01-01
      • 2017-01-25
      • 1970-01-01
      • 2019-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多