为啥我的程序在管理这个 JSON 文件时会崩溃?

Posted

技术标签:

【中文标题】为啥我的程序在管理这个 JSON 文件时会崩溃?【英文标题】:Why does my program crash when managing this JSON file?为什么我的程序在管理这个 JSON 文件时会崩溃? 【发布时间】:2021-08-06 08:40:57 【问题描述】:

只要有人发送!setmainchannel,我的程序就会崩溃。我正在使用带有包 discord.js 的 Node.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 channel\n`);
      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 online\n');
);

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

main-channel.json:


    "channel":null

【问题讨论】:

任何错误信息? @SuperStormer 没有错误消息发生,但我现在意识到该程序什么都不做并继续接受任何其他命令 【参考方案1】:

首先,您的机器人什么都不做,因为它只对if (msg.content == "!setmainchannel") 做出反应。如果您提供参数,例如频道 (!setmainchannel #ch-name),它将不会运行,因为消息的内容不完全是前缀和命令。

您需要先解决这个问题。通过删除前缀并切掉参数,您可以获得命令本身并检查是否使用了这个确切的命令。 (同样,你不应该检查整个message.content

其次,您不必等待readFile 内部的回调运行。这意味着,当您尝试更新currentSettings.channel 时,您的jsonRead() 函数刚刚开始读取文件并且currentSettingsundefined。您将无法更新其channel 属性。

我已更新您的 jsonWritejsonRead 函数以返回承诺并使其更易于使用。检查下面的工作代码:

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 channel\n`);
      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 online\n');
);

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") 做出反应!

【讨论】:

不,这不是唯一的错误。仅仅改变它并不能解决问题,它仍然会导致 TypeError。有关详细信息,请参阅我的答案。

以上是关于为啥我的程序在管理这个 JSON 文件时会崩溃?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 .NET 应用程序从网络驱动器运行时会崩溃?

为啥在使用 OpenGL 核心配置文件时会崩溃?

为啥我的 iOS 应用程序在收到推送通知时会崩溃?

为啥我的 Flutter 应用在​​ iOS 上启动时会崩溃?

为啥我在退出我的 Activity 时会崩溃?

为啥我的应用在使用 cloudkit 时会崩溃?