【问题标题】:TypeError: Cannot read properties of undefined (reading '0') discord.js v13TypeError:无法读取未定义的属性(读取“0”)discord.js v13
【发布时间】:2022-02-16 00:21:23
【问题描述】:

出于某种愚蠢的原因,我正在使用 Discord.JS v13。自从我得到这些奇怪的错误以来,我不知道存在。每次我运行该命令时,它都会给出一个错误并关闭机器人。我尝试添加try and catch,但我认为这些不再适用于v13。如果你们可以提供帮助,这是我的代码。

错误在第 32 行 btw

const Discord = require('discord.js')
const { MessageEmbed } = require('discord.js')
const https = require('https')
const url = 'https://www.reddit.com/r/catpics/hot/.json?limit=300'
module.exports = {
    name: "cat",
    description: "meow",
     execute(message, args, client) {
        message.reply("I am loading the image, if it does not come up try again later due to errors.")
        https.get(url, (result) => {
            var body = ''
            result.on('data', (chunk) => {
                body += chunk
            })

            result.on('end', () => {
                var response = JSON.parse(body)
                var index = response.data.children[Math.floor(Math.random() * 99) + 1].data

                if (index.post_hint !== 'image') {

                    var text = index.selftext
                    const textembed = new Discord.MessageEmbed()
                        .setTitle("cute")
                        .setColor(9384170)
                        .setDescription(`[${title}](${link})\n\n${text}`)
                        .setURL(`https://reddit.com/${subRedditName}`)

                    message.channel.send({embeds: [textembed]})
                }

                var image = index.preview.image[0].source.url.replace('&', '&')
                var title = index.title
                var link = 'https://reddit.com' + index.permalink
                var subRedditName = index.subreddit_name_prefixed

                if (index.post_hint !== 'image') {
                    const textembed = new Discord.MessageEmbed()
                        .setTitle("cute")
                        .setColor(9384170)
                        .setDescription(`[${title}](${link})\n\n${text}`)
                        .setURL(`https://reddit.com/${subRedditName}`)

                    message.channel.send({embeds: [textembed]})
                }
                console.log(image);
                const imageembed = new Discord.MessageEmbed()
                    .setTitle("cute")
                    .setImage(image)
                    .setColor(9384170)
                    .setDescription(`[${title}](${link})`)
                    .setURL(`https://reddit.com/${subRedditName}`)
                message.channel.send({embeds: [imageembed]})
            }).on('error', function (e) {
                console.log('Got an error: ', e)
            })
        })

     }
}

输出:

TypeError: Cannot read properties of undefined (reading '0')

【问题讨论】:

  • 当然,您确定indexindex.previewindex.preview.image 存在,对吧?在尝试访问 index.preview.image[0] 之前尝试记录它们,您可能会得到答案。
  • 它不会让我记录它们,它只是发送错误然后一切都崩溃
  • 你有办法记录吗?
  • 如果我记录索引、index.preview 或 index.preview.image 控制台会出现错误并显示:TypeError: Cannot read properties of undefined (reading 'image')
  • 那么它的意思就是它所说的:There is no key named "preview" in the variable you are logging (index)Trying to read "image" from a key that is undefined。甚至 index 也可能是未定义的。

标签: node.js discord discord.js


【解决方案1】:

由于我猜你没有编程背景,我将检查你可能从示例中复制粘贴和/或适应你的需要的代码的每一部分,并尝试深入解释哪些行为当出现任何错误时,您应该采用。一旦我们到达错误行,我就会停下来,line 32

请记住,这不是一个地方,但我会一次性完成。合适的位置是Stack Exchange's Code Review

首先,鉴于urlhttps 模块的存在,我假设您尝试从Reddit 检索有关猫图片的信息。

让我们直接深入讨论有代码的地方。 result.on('end') 函数将在没有更多要解析的主体时执行,但我想你明白了。

然后,您尝试检索随机选择的特定图像的数据:

var index = response.data.children[Math.floor(Math.random() * 99) + 1].data

这里有两件事:

  • Math.random() 只返回一个介于 01 之间的数字,这使得整行选择了一个介于 1 和 100 之间的数字。然后您就错过了选择元素 0 的机会,因为 JS 中的数组是从零开始索引的。此外,您可以将 Reddit URL 中的限制从 300 减少到 100。
  • 您假设 2 件事:children 确实是 Reddit 发回给您的response 的键,并且children 数组最多包含 100 个元素。

如果children 数组只有 15 个元素(如果存在的话)会怎样?您将遇到另一个错误。我会让你想出一个解决方案来检查这两个问题。

那里:

var image = index.preview.image[0].source.url.replace('&', '&')

你再次假设previewimage(作为一个数组)、sourceurl存在。

现在我继续将 URL https://www.reddit.com/r/catpics/hot/.json?limit=100 的结果复制粘贴到 JSON Beautifier 中,碰巧您在第 32 行询问的 preview 存在,但是,image don不。

您只是忘记了s,因为images 存在于preview 下。

事实上,你的错误归结为两件事:

  1. 变量 index 可能未定义,因为您可能会尝试使用无法访问的索引访问 response.data.children 数组(例如,response.data.children 只有 15 个元素,而您的 Math.random 为您提供 55 个元素)
  2. image 字段在 preview 中不存在,只有 images 存在。

最后,为了说明你得到的TypeError,就像让别人给你读一张完全空白的纸,或者给一个盲人写一篇文章,让他给你读。

无论哪种方式,在此处提出问题之前,您都应该更加努力。如果您尝试在每行之间登录直到缩小错误范围,您可能已经自己弄清楚了。

另外,如果这些是weird errors that I had no idea exists,那么您还没有真正准备好编写代码。我每天收到这些TypeError 六次,如果不是更多的话。这听起来可能很苛刻,但你不能来为你遇到的任何轻微的不便寻求帮助,否则你不会学到任何东西。更不用说你没有发布minimum reproducible example

话虽如此,如果我提到的你应该解决的两件事不能解决问题,我会留在 cmets 中。


在这个答案的 cmets 之后,我将添加更多详细信息。我还将介绍如何解决该问题,以便 OP 可以将类似的想法和程序应用于其他问题。

如果您继续 this page,这是您的代码中存在的 URL,但不是 JSON 形式,您会看到有些帖子要排除。通常,我不认为来自TrendingBot 的帖子很有趣,因此您可以将它们排除在外。这就是为什么你有/r/catpics enters TOP 5000 subreddits。任何有index.author === 'TrendingBot' 的东西都不是bueno。

对于其他问题,您可以通过 JSON 美化器(我在上面链接的)检查键和值。

看着自己美化的 JSON,我不认为您正在寻找关于 image 的正确密钥。您可能想要显示的图像是index.url 键下的图像,这是实际帖子的图像。我真的不认为preview 是您应该搜索的内容。

最后,对于链接,我不认为您正在寻找正确的键。我认为你应该使用index.permalink 而不是index.subreddit_name_prefixed

您的最终消息应如下所示:

const image = index.url.replace('&', '&');
const title = index.title;
const link = 'https://reddit.com' + index.permalink;
const subRedditName = index.subreddit_name_prefixed;

const imageembed = new Discord.MessageEmbed()
                    .setTitle("cute")
                    .setImage(image)
                    .setColor(9384170)
                    .setDescription(`[${title}](${link})`)
                    .setURL(link);

【讨论】:

  • 多亏了你,我修复了错误,但现在它只是发送这个? ibb.co/Cvr5DwW有没有办法不发送“前5000”之类的?
  • 如果我点击它会跳转到评论链接,为什么我没有将评论部分添加到 url 时它是 cmets?
  • 仍然一直说 TypeError: Cannot read properties of undefined (reading 'images') also
  • 请给我几分钟来编辑我的原始答案。
  • 非常感谢