For some dumb reason, I am using Discord.JS v13. And ever since I have been getting these weird errors that I had no idea exists. Every time I run the command it just gives an error and shuts down the bot. I tried adding the try and catch but those dont work for v13 anymore I dont think. Here is my code if you guys can help.
The error is at line 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)
})
})
}
}
Output:
TypeError: Cannot read properties of undefined (reading '0')
CodePudding user response:
Since I'm guessing you have no background on programmation, I'm gonna go over every part of the code you probably copy-pasted from an example and/or adapted to your needs and try to explain in-depth what behavior you should adopt when any error comes. I'll stop once we reach the line of the error, line 32
.
Keep in mind that it is not the place but I'm gonna do it as a one-time thing. The appropriate place would be Stack Exchange's Code Review.
First, given the url
and the presence of https
module, I assume you try to retrieve informations about pictures of cats from Reddit.
Let's dive directly where there's code to discuss. The result.on('end')
function will be executed when there is no more body to parse, but I think you got that.
Then, you try to retrieve data about a particular image, chosen at random:
var index = response.data.children[Math.floor(Math.random() * 99) 1].data
Two things from here:
- Math.random() only returns a number between
0
and1
, making this whole line chosing a number between 1 and 100. You then miss the opportunity to chose the element 0, since Arrays in JS are zero-based indexed. Also, you can reduce the limit in your Reddit URL from 300 to 100. - You assume 2 things: that
children
is indeed a key of theresponse
Reddit sent you back, AND that thechildren
array goes up to 100 elements.
What happens if children
array has only, say 15 elements (if it exists at all)? You will have another error. I'll leave it to you to come up with a solution to check both things.
There:
var image = index.preview.image[0].source.url.replace('&', '&')
you once again assume that preview
, image
(as an array), source
, and url
exist.
Now I've gone ahead and copy-pasted the result of the URL https://www.reddit.com/r/catpics/hot/.json?limit=100
in a JSON Beautifier, and it happens that the preview
you're asking on line 32 exists, however, image
don't.
You only forgot an s
, since images
exists under preview
.
In fact, your error comes down to two things:
- The variable
index
might be undefined because you might try to accessresponse.data.children
array with an unreachable index (e.gresponse.data.children
has only 15 elements and your Math.random gives you 55) image
field doesn't exist inpreview
, onlyimages
do.
Finally, to illustrate the TypeError
you got, it is like asking someone to read you a completely blank paper, or giving an essay to a blind person and telling him to read it for you.
Either way, before asking a question on here, you should try a little harder. You could have figured it out yourself if you tried to log in between each line until narrowing down the error.
Also, if these are weird errors that I had no idea exists
, then you're not really ready to code yet. I get these TypeError
a half-dozen times a day if not more. That may sound harsh but you can't come and ask for help for any minor inconvenience you come across, or else you won't learn anything. Not to mention you didn't post a minimum reproducible example.
With all that said, I stay available in the comments if the two things I mentioned you should fix don't solve the issue.
Following the comments on this answer, I'll add more details. I'll go through how to resolve the issue as well, so OP can apply similar thinking and procedures for other problems.
If you go on this page, which is the URL present on your code, only not in JSON form, you will see that there are posts that you want to exclude. Typically, I don't think the posts from TrendingBot
are interesting, so you can just exclude them. That is why you were having /r/catpics enters TOP 5000 subreddits
. Anything that has index.author === 'TrendingBot'
is no bueno.
For the others matters, you can inspect keys and values via a JSON beautifier (that I linked above).
Looking at the JSON beautified myself, I don't think you're searching for the right key regarding the image
. The image you probably want to display is the image under the index.url
key, which is the image of the actual post. I really don't think preview
is what you should be searching for.
Finally, for the link, again, I don't think you're searching for the right key. I think you should grab index.permalink
instead of index.subreddit_name_prefixed
.
Your final message should look something like this:
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);