Мы пытаемся заставить наш триггер событий guildCreate.js работать для Corion. Но он выдает следующую ошибку:

3|Corion | (node:16154) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'cache' of undefined

Здесь представлен наш код:

module.exports = async (client, guild) => {
    const channel = guild.channels.cache.find(channel => channel.type === 'text' && channel.permissionsFor(guild.me).has('SEND_MESSAGES'))
    console.log(`${client.name}` + `has entered` + `${guild.name}.`)
    channel.send(`Спасибо за приглашение!`\n\nType **c!help** для просмотра полного списка доступных команд!`).catch(console.error)
};

Это наш обработчик событий, если это поможет:

const events = fs.readdirSync('./events').filter(file => file.endsWith('.js'));

for (const file of events) {
    console.log(`Загрузка события discord.js ${файл}`);
    const event = require(`./events/${file}`);
    client.on(file.split(".")[0], event.bind(null, client));
};

У нас работает discord.js: 12.5.1

Joshua Lewis

Ответов: 1

Ответы (1)

Это не сработает в данной конкретной ситуации из-за того, как работает обратный вызов client.on("guildCreate"). На самом деле, вы можете обнаружить, что это не будет работать должным образом практически для всех различных событий Discord из-за того, как работают обратные вызовы в сочетании с тем, как вы используете .bind().

Проблема

Подумайте о том, как работает client.on() с точки зрения обратного вызова. При использовании client.on() вы делаете примерно следующее: client.on("guildCreate", callback). И вот что делает client.on(), когда срабатывает это событие: он вызывает callback(guild).

А теперь подумайте о том, что вы делаете в своем коде. Вы выполняете event.bind(null, client) в функции обработчика событий, которая имеет форму callback(client, guild). Вот что происходит:

  1. Вы установили значение client в обратном вызове для вашего Discord.Client, через .bind(). Итак, теперь ваш параметр client - Discord.Client, а параметр guild - undefined.
  2. Когда событие срабатывает, оно теперь устанавливает ваш первый параметр (client) в объект Guild. Так что теперь ваш параметр client - это Guild, а параметр guild по-прежнему undefined.
  3. .
  4. Сейчас в обратном вызове вы пытаетесь сделать guild.channels.cache. guild все еще не определен, поэтому guild.channels не определен, и поэтому вы получаете ошибку: Cannot read property 'cache' of undefined.

Решение

Так как же решить эту проблему? Ну, вашим первым побуждением может быть просто изменить порядок параметров client и guild в обратном вызове, а затем соответствующим образом настроить .bind(). Это может сработать для данного конкретного события, но помните, что некоторые события имеют два или более параметров в своих обратных вызовах. guildCreate отправляет вам только один аргумент гильдии, а что-то вроде guildUpdate отправляет вам два (что, соответственно, вызывает точно такую же ошибку, с которой вы сейчас столкнулись).

Какое бы решение вы ни выбрали, вам придется полностью отказаться от параметра client. Если вы хотите учитывать любое количество параметров и при этом использовать удобный метод .bind(), то вместо привязки клиента к первому параметру обратного вызова вы можете привязать клиента к ключевому слову this. Вот пример того, что я имею в виду:

Обработчик события:

const events = fs.readdirSync('./events').filter(file => file.endsWith('.js'));

for (const file of events) {
    console.log(`Loading discord.js event ${file}`);
    const event = require(`./events/${file}`);
    client.on(file.split(".")[0], event.bind(client));
};

guildCreate.js:

module.exports = async function (guild) {
    const client = this;
    const channel = guild.channels.cache.find(channel => channel.type === 'text' && channel.permissionsFor(guild.me).has('SEND_MESSAGES'))
    console.log(`${client.user.username}` + `has entered` + `${guild.name}.`)
    channel.send(`Thanks for invite me!\n\nType **c!help** to see a full list of available commands!`).catch(console.error)
};

Это должно гарантировать, что client.on() не изменит значение client, и, следовательно, устранит специфическую ошибку, с которой вы столкнулись.

Что изменилось

В целом, вам нужно: изменить .bind(null, client) на .bind(client) в обработчике событий, удалить параметр client из обратного вызова guildCreate.js, использовать this для доступа к клиенту, изменить client.name на client.user.username, поскольку первый вариант некорректен, и переключитесь со стрелочных функций ES6 (() => {}) на стандартный синтаксис функций (function() {}) из-за того, как ключевое слово this работает в первом варианте.

.

Я не тестировал это решение, но гипотетически оно должно сработать, чтобы, по крайней мере, решить ошибку, с которой вы столкнулись в данный момент. Сообщите мне, если это не так, или если в этом коде есть другие ошибки, и я отредактирую ответ, чтобы исправить их.

2022 WebDevInsider