UserErrors not being caught by listener - bot is crashing

messageCommandError.mjs
import { Events, Listener } from "@sapphire/framework";
import { send } from "@sapphire/plugin-editable-commands";
import { EmbedBuilder } from "discord.js";

export class UserEvent extends Listener {
constructor(context, options) {
super(context, {
...options,
once: false,
event: Events.MessageCommandError,
name: "messageCommandError",
});
}

async run({ context, message: content }, { message: msg }) {
// `context: { silent: true }` should make UserError silent:
// Use cases for this are for example permissions error when running the `eval` command.
if (Reflect.get(Object(context), "silent")) return;

const embed = new EmbedBuilder()
.setTitle("Command Failed")
.setDescription(content)
.setColor("Red")
.setTimestamp();

return send(msg, {
embeds: [embed],
allowedMentions: { users: [msg.author.id], roles: [] },
});
}
}
import { Events, Listener } from "@sapphire/framework";
import { send } from "@sapphire/plugin-editable-commands";
import { EmbedBuilder } from "discord.js";

export class UserEvent extends Listener {
constructor(context, options) {
super(context, {
...options,
once: false,
event: Events.MessageCommandError,
name: "messageCommandError",
});
}

async run({ context, message: content }, { message: msg }) {
// `context: { silent: true }` should make UserError silent:
// Use cases for this are for example permissions error when running the `eval` command.
if (Reflect.get(Object(context), "silent")) return;

const embed = new EmbedBuilder()
.setTitle("Command Failed")
.setDescription(content)
.setColor("Red")
.setTimestamp();

return send(msg, {
embeds: [embed],
allowedMentions: { users: [msg.author.id], roles: [] },
});
}
}
44 Replies
Spinel
Spinel2y ago
- Which version of @sapphire/framework are you using? - What's your file/folder structure? - Did you use the CLI to generate your bot? - What's your "main" property in package.json - Are you using TypeScript? And if so, how are you compiling and running your code? That is to say, what are your build and startup scripts? - In case you are using version 3.0.0 or higher of @sapphire/framework, and your problem related to message commands, did you add loadMessageCommandListeners to your SapphireClient options Remember that if you are new to @sapphire/framework it is important that you read the user guide. When asking for help, make sure to provide as much detail as possible. What have you tried so far? Do you have stacktraces that you can show us? What are you trying to achieve? Try to answer these questions and others, so we do not have to ask for them afterwards.
❯ For a good guide on how to ask questions, see the instructions that StackOverflow gives. You should try to always follow these guidelines. ❯ For an excellent video that shows how not to ask technical questions is this, watch this YouTube video by LiveOverflow. ❯ Asking technical questions (Clarkson)How to ask questions the smart way (Raymond)
disclosuure
disclosuureOP2y ago
- Which version of @sapphire/framework are you using? latest - What's your file/folder structure? attached - Did you use the CLI to generate your bot? no - What's your "main" property in package.json? src/index.js - Are you using TypeScript? And if so, how are you compiling and running your code? That is to say, what are your build and startup scripts? no - In case you are using version 3.0.0 or higher of @sapphire/framework, and your problem related to message commands, did you add loadMessageCommandListeners to your SapphireClient options? yes
disclosuure
disclosuureOP2y ago
[INFO] ApplicationCommandRegistries: Initializing...
[INFO] Successfully logged in as Clanware-Bot (912430259960422401)
[INFO] ApplicationCommandRegistries: Took 326ms to initialize.

UserError: That group doesn't exist or isn't affiliated yet.
at AddPointsCommand.run (file:///C:/Users/x/Downloads/Clanware3/src/commands/admin/addpoints.mjs?d=1679773740629&name=addpoints&extension=.mjs:45:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
identifier: undefined,
context: null
}
[nodemon] app crashed - waiting for file changes before starting...
[INFO] ApplicationCommandRegistries: Initializing...
[INFO] Successfully logged in as Clanware-Bot (912430259960422401)
[INFO] ApplicationCommandRegistries: Took 326ms to initialize.

UserError: That group doesn't exist or isn't affiliated yet.
at AddPointsCommand.run (file:///C:/Users/x/Downloads/Clanware3/src/commands/admin/addpoints.mjs?d=1679773740629&name=addpoints&extension=.mjs:45:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
identifier: undefined,
context: null
}
[nodemon] app crashed - waiting for file changes before starting...
Favna
Favna2y ago
whats the code for addpoints.mjs
disclosuure
disclosuureOP2y ago
let me upload it one sec
Favna
Favna2y ago
if you can put the full code on GH that would probably be faster
Favna
Favna2y ago
const amount = parseInt(args[1]); should at best be const amount = Number(args[1]); btw because messageRun passes the arguments as number, number, not as string, string or better yet just make group-id for chat input a number and dont parseInt or cast at all
disclosuure
disclosuureOP2y ago
group-id can be large though which is why i parse as a string
disclosuure
disclosuureOP2y ago
GitHub
GitHub - cosigyn/Clanware-V3
Contribute to cosigyn/Clanware-V3 development by creating an account on GitHub.
Favna
Favna2y ago
that doesnt matter for discord options...
disclosuure
disclosuureOP2y ago
doesnt node.js have difficulty with large numbers
Favna
Favna2y ago
no...
disclosuure
disclosuureOP2y ago
i see
Favna
Favna2y ago
well unless it exceeds 9007199254740991 I suppose which is Number.MAX_SAFE_INTEGER but that would go for any language and again, then you should also parse it as a string for messageRun however messageRun as await args.pick('number') so you're not doing that
disclosuure
disclosuureOP2y ago
yeah its possible, and you're right but do you know if I'm doing something wrong with the user errors?
Favna
Favna2y ago
should also note that usage isnt a valid command option and if you want detailed help for help you should put it in detailedDescriptionso:
detailedDescription: {
usage: 'addpoints <group id> <amount>',
emoji: '💯'
}
detailedDescription: {
usage: 'addpoints <group id> <amount>',
emoji: '💯'
}
otherwise it'll just end up getting nuked at runtime without proper class extensions which you're not doing - and using detailedDescription is better anyway
disclosuure
disclosuureOP2y ago
i plan to access it and the emoji later for a help command but ill look into detailed description
Favna
Favna2y ago
command.detailedDescription.usage vs command.usage ezpz
disclosuure
disclosuureOP2y ago
oh i see i thought it only accepted a string
Favna
Favna2y ago
except that the latter would mean you'd have to extend the sapphire comand class and add the properties for no real reason string | DetailedDescriptionCommand | undefined is the type with DetailedDescriptionCommand being an empty interface to allow TS users to module augment it anyway
disclosuure
disclosuureOP2y ago
yes i havent extensively looked into the docs aside from the guide
Favna
Favna2y ago
as for the error The only thing you are missing is the identifier but I don't think that would prevent it from being caught by the listener
Favna
Favna2y ago
here is the fixed up file
Favna
Favna2y ago
or not, thjanks for the embed discord https://hastebin.skyra.pw/ayobayoxeb.mjs
disclosuure
disclosuureOP2y ago
thanks
Favna
Favna2y ago
can you try making sure that loadDefaultErrorListeners is true in your client options? see if it gets caught then
disclosuure
disclosuureOP2y ago
yeah its true
Favna
Favna2y ago
oh.. well then try with the fixed up file at least seeing as you were missing various things I fixed: - this.run not being awaited - the consistency of string vs number as we discussed above - adding identifier to all the throws - (messageRun) switching from pick(..).catch(() => null) to pickResult - (messageRun) removing the NaN check for amount because args.pickResult('number') already does that - (chatInputRun) marking group-id and amount as required - (run) properly checking if the channel is available before trying to send a message to it - (run) removing the number parsing for amount
disclosuure
disclosuureOP2y ago
this worked thank you also, how do i prevent it from showing in the console, if the error is handled?
Favna
Favna2y ago
false here
disclosuure
disclosuureOP2y ago
i see
Favna
Favna2y ago
Just saying, these are all runtime fixes that were all raised by simply dumping the code in a TypeScript file (.mts, to match the .mjs). I understand if TypeScript may be daunting to learn but I can very strongly recommend you do. note: see #Announcements -> stick to TS 4.9.5 for now until we have time to bring out new releases.
Favna
Favna2y ago
correction: exception goes to the top point which wasn't so much typescript itself as the ESLint plugin for typescript code. That said, they kinda go hand-in-hand.
disclosuure
disclosuureOP2y ago
I haven't really used ESM at all before, but I will start to look into types and things - I don't really understand many of the core concepts yet
Favna
Favna2y ago
kudos that you're starting with ESM right away though many people would have stuck to CJS and you already figured out the hashes for importing rather than using relative paths, that's also something a lot of people struggle with
disclosuure
disclosuureOP2y ago
i got sick of packages not supporting cjs
Favna
Favna2y ago
ironically there are also packages that don't support ESM omegalul
disclosuure
disclosuureOP2y ago
ah 💀
Favna
Favna2y ago
but ESM is the future I don't expect it to happen any time soon but Node will deprecate then remove CJS eventually
disclosuure
disclosuureOP2y ago
I haven't used JS outside of node.js so ig that's why I've been using CJS Also would you recommend setting up an event emitter for success responses/logging user actions
Favna
Favna2y ago
For @Dragonite I have it but I only load it when logging level is set to debug and that's only the case when NODE_ENV is 'development' Dragonite and other bots are open source btw:
Spinel
Spinel2y ago
Discord bots that use @sapphire/framework v4 - Official Bot Examples ᴱ ᴰ ᴶˢ - Archangel ᴱ ᴰ - Dragonite ᴱ ᴰ - Radon ᴱ ᴬ Discord bots that use @sapphire/framework v3 - Arima ᴱ - Nino ᴱ ᴰ - Operator ᴱ ᴬ ᴰ - Sapphire Application Commands Examples ᴱ - Spectera ᴬ Discord bots that use @sapphire/framework v2 - Materia ᴱ - RTByte ᴱ ᴬ - Skyra ᴬ ᴰ - YliasDiscordBot ᴬ : Uses ESM (if not specified then uses CJS) : Advanced bot (if not specified it is a simple bot, or not graded) : Uses Docker in production ᴶˢ: Written in JavaScript. If not specified then the bot is written in TypeScript.
disclosuure
disclosuureOP2y ago
thanks
Want results from more Discord servers?
Add your server