#Precondition not triggering "chatInputCommandDenied"

1 messages · Page 1 of 1 (latest)

gusty moon
#

I have setup the following precondition:

#

Precondition not triggering "chatInputCommandDenied"

#

ValidAutocompletedObjectIdArguments.ts

import { Precondition } from '@sapphire/framework';
import { ChatInputCommandInteraction, inlineCode } from 'discord.js';
import { Types } from 'mongoose';
import { RealmAutocompleteInteractionHandler } from '../interaction-handlers/RealmAutocompleteInteractionHandler.js';
import ZoneModeAutocompleteInteractionHandler from '../interaction-handlers/ZoneModeAutocompleteInteractionHandler.js';
import { RaidAutocompleteInteractionHandler } from '../interaction-handlers/RaidAutocompleteInteractionHandler.js';

export class ValidAutocompletedObjectIdArgumentsPrecondition extends Precondition {
    private _autocompletedObjectIdOptionNames: string[] = [
        RealmAutocompleteInteractionHandler.optionName,
        ZoneModeAutocompleteInteractionHandler.optionName,
        RaidAutocompleteInteractionHandler.optionName
    ];

    public constructor(context: Precondition.LoaderContext, options: Precondition.Options) {
        super(context, {
            ...options
        });
    }

    public override async chatInputRun(interaction: ChatInputCommandInteraction) {
        interaction.options.data.forEach((option) => {
            if (
                this._autocompletedObjectIdOptionNames.includes(option.name) &&
                option.value &&
                typeof option.value === 'string' &&
                !Types.ObjectId.isValid(option.value)
            ) {
                return this.error({
                    message: `Invalid parameter value for ${inlineCode(option.name)}. Please select one of the autocompleted options.`
                });
            }

            return;
        });

        return this.ok();
    }
}

declare module '@sapphire/framework' {
    interface Preconditions {
        ValidAutocompletedObjectIdArguments: never;
    }
}
#

However, my chatInputCommandDenied listener isn't firing:

ChatInputCommandDenied.ts

import { ChatInputCommandDeniedPayload, Events, Listener, type UserError } from '@sapphire/framework';
import Utils from '../lib/Utils.js';
import { CustomEmbedType } from '../ui/embeds/CustomEmbed.js';

export class ChatInputCommandDeniedListener extends Listener<typeof Events.ChatInputCommandDenied> {
    public constructor(context: Listener.LoaderContext, options: Listener.Options) {
        super(context, {
            ...options,
            event: 'chatInputCommandDenied'
        });
    }

    public async run(error: UserError, payload: ChatInputCommandDeniedPayload) {
        try {
            if (!payload.interaction.deferred) await payload.interaction.deferReply({ ephemeral: true });

            const reply = await payload.interaction.editReply({
                embeds: [
                    (await this.container.ui.embeds.create(CustomEmbedType.Error)) //
                        .setDescription(error.message)
                ],
                components: []
            });

            Utils.deleteAfterDelay(reply, payload.interaction.webhook);
        } catch (reason) {
            this.container.logger.error(reason);
        }
    }
}
#

I know for a fact that the precondition is firing & returning an error in my test, as I've added a breakpoint to the return this.error (...) statement

#

And here's the setting of the precondition on the command:

CMServerDefaults.ts

export class CMServerDefaultsCommand extends Command {
    public constructor(context: Command.LoaderContext, options: Command.Options) {
        super(context, { ...options, preconditions: ['ValidAutocompletedObjectIdArguments'] });
    }

(...)
agile nexus
#

FYI if youu name the file chatInputCommandDenied (camel cased) then you dont need to set the event property at all anymore and you can fully omit the constructor.
Alternatively you can also use the enum that you already use as a type instead of the hard coded string: event: Events.ChatInputCommandDenied

#

Ah I also see where you're going wrong here. Yes you land on the breakpoint for this.error, however because you're using Array#forEach which accepts a callback function that returns void you're not actually returning this.error for the function chatInputRun but rather for the anonymous arrow function that is provided to Array#forEach.
You can solve this by using for...of instead.

gusty moon