Почему моя программа выходит из строя при управлении этим файлом JSON?

#javascript #node.js #json #discord.js

Вопрос:

Всякий раз , когда кто-то отправляет !setmainchannel , моя программа выходит из строя. Я использую Node.js вместе с пакетом discord.js. Это единственная проблема, которая у меня есть. Я не понимаю и не могу понять, в чем дело, и я был бы чрезвычайно признателен, если бы кто-нибудь мог мне помочь.

bot.js :

 let Discord = require("discord.js");
let client = new Discord.Client();
let fs = require('fs');

let help = require("./helpembed.json");

var jsonRead = function(filePath){
  fs.readFile(filePath, 'utf-8', (err, returnJson) => {
    if(err){
      console.log(err);
    }
    else{
      let ret = JSON.parse(returnJson);
      return ret;
    }
  })
}

var jsonWrite = function(filePath, objIn){
  fs.writeFile(filePath, JSON.stringify(objIn), err => {
    if(err){
      console.log(err);
    }
  })
}

client.on("message", msg => {
  let time = new Date();
  let cstTimeStamp = `${time.getMonth()   1}/${time.getDate()}/${time.getFullYear()} ${time.getHours()   1}:${time.getMinutes()}:${time.getSeconds()}`

  if(msg.content == "!setmainchannel"){
    let mainChannel = msg.mentions.channels.first();

    if(!mainChannel){
      console.log(`${cstTimeStamp} @${msg.author.tag} requested to set a main channel but didn't provide a channeln`);
      msg.channel.send("There's no channel to set the main to");
    }
    else{
      let currentSettings = jsonRead("./main-channel.json");
      currentSettings.channel = mainChannel;
      jsonWrite("./main-channel.json", currentSettings);
      console.log(`${cstTimeStamp} @${msg.author.tag} set the main channel as ${currentSettings.channel}n`);
      msg.channel.send(`Set the main channel as ${currentSettings.channel}`);
    }
    
  }
})

client.once('ready', () => {
    console.log('Bot is onlinen');
});

client.login('Token hidden for safety reasons');
 

main-channel.json :

 {
    "channel":null
}
 

Комментарии:

1. Какие-нибудь сообщения об ошибках?

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

Ответ №1:

Во-первых, ваш бот ничего не делает, потому что он только реагирует if (msg.content == "!setmainchannel") . Если вы предоставите аргумент, например channel ( !setmainchannel #ch-name ), он не будет запущен, поскольку содержимое сообщения не является префиксом и командой.

Сначала тебе нужно это исправить. Удалив префикс и отключив аргументы, вы можете получить саму команду и проверить, используется ли именно эта команда. (Опять же, вы не должны проверять все целиком message.content )

Во-вторых, вы не ждете, пока запустится обратный вызов внутри readFile . Это означает, что при попытке обновления currentSettings.channel ваша jsonRead() функция только что начала считывать файл и currentSettings это undefined . Вы не сможете обновить его channel свойство.

Я обновил ваши jsonWrite функции и jsonRead функции, чтобы вернуть обещания и упростить их использование. Проверьте рабочий код ниже:

 const Discord = require("discord.js");
const fs = require('fs');
const path = require('path');

const client = new Discord.Client();
const prefix = '!';

client.on('message', async (msg) => {
  // create an args variable that slices off the prefix and splits it into an array
  const args = msg.content.slice(prefix.length).split(/  /);
  // create a command variable by taking the first element in the array
  // and removing it from args
  const command = args.shift().toLowerCase();
  const cstTimeStamp = new Date().toLocaleString();

  if (command === 'setmainchannel') {
    const mainChannel = msg.mentions.channels.first();
    const filePath = path.resolve(__dirname, './main-channel.json');

    if (!mainChannel) {
      console.log(`${cstTimeStamp} ${msg.author.tag} requested to set a main channel but didn't provide a channeln`);
      return msg.channel.send("There's no channel to set the main to");
    }

    try {
      const currentSettings = await jsonRead(filePath);
      currentSettings.channel = mainChannel;

      jsonWrite(filePath, currentSettings);

      console.log(`${cstTimeStamp} ${msg.author.tag} set the main channel as ${currentSettings.channel}n`);
      msg.channel.send(`Set the main channel as ${currentSettings.channel}`);
    } catch (err) {
      console.log(err);
    }
  }
});

client.once('ready', () => {
    console.log('Bot is onlinen');
});

client.login('Token hidden for safety reasons');

function jsonRead(filePath) {
  return new Promise((resolve, reject) => {
    fs.readFile(filePath, 'utf-8', (err, content) => {
      if (err) {
        reject(err);
      } else {
        try {
          const parsedContent = JSON.parse(content);
          resolve(parsedContent);
        } catch (err) {
          reject(err);
        }
      }
    });
  });
}

function jsonWrite(filePath, data) {
  return new Promise((resolve, reject) => {
    fs.writeFile(filePath, JSON.stringify(data), (err) => {
      if (err) {
        reject(err);
      }
      resolve(true);
    });
  });
}
 

введите описание изображения здесь

Ответ №2:

Ладно, я понимаю, что здесь происходит. Я заставил логику реагировать ТОЛЬКО !setmainchannel на ЭТО , в то время как я должен был это сделать if(msg.content.startsWith("!setmainchannel") !

Комментарии:

1. Нет, это не единственная ошибка. Изменение только этого не решит проблему, и это все равно приведет к ошибке типа. Смотрите мой ответ для получения более подробной информации.