首页 > 解决方案 > Force discord to display failed interaction message

问题描述

Discord will automatically time out and trigger a custom "This interaction failed" message if the application fails to respond to an interaction within 3s.

I am however running some slightly longer tasks, so I'm calling the ctx.defer() method, which gives me more time to respond and displays a "<application_name> is thinking..." animation discord-side.

Should my task raise some internal exception, I'd like to manually trigger the "This interaction failed" message. Does the discord API expose a method to do so?

The message I'm trying to trigger

A dummy example, using discord-py-slash-command:

import discord
from discord.ext import commands
from discord_slash import SlashCommand, SlashContext

bot = commands.Bot(command_prefix="!", intents=discord.Intents.all())
slash = SlashCommand(bot)

@slash.slash(name="test")
async def _test(ctx: SlashContext):
    await ctx.defer()
    try:
        assert 1==2
    except AssertionError:
        # Somehow trigger the error message

bot.run("discord_token")

标签: pythondiscorddiscord.jsdiscord.py

解决方案


The documentation states, that defering a message will allow an update of the message for up to 15 minutes. There is no intented way of failing the interaction early, however you could try sending an invalid/broken response on purpose and see if that invalidates the pending interaction.

However this is far from good practice and not possible within the implementation limits of the discord-py-slash-command library.

I would recommend to manually invoke an error response to show the user a better error response. A failed interaction can have many reasons from buggy code to complete unavailability of your service and doesn't really help the user.

Expected errors

You can simply respond with a hidden user message.

ctx.send('error description', hidden=True)
return

For this to work, you must first defer the message in a hidden stage aswell ctx.defer(hidden=True). If you want the final answer to be seen for all users on the server, you can either send a normal message on-top (ctx.channel.send) or you can show the error message as a public message, by using the 'normal' defer.

Unexpected errors

To catch unexpected errors, I'd suggest listening to the on_slash_command_error event handler.

@client.event
async def on_slash_command_error(ctx, error):

    if isinstance(error, discord.ext.commands.errors.MissingPermissions):
        await ctx.send('You do not have permission to execute this command', hidden=True)

    else:
       await ctx.send('An unexpected error occured. Please contact the bot developer', hidden=True)
       raise error  # this will show some debug print in the console, when debugging

Note that the response will only be hidden if the previous defer was called as ctx.defer(hidden=True). If ctx.defer() was used, the execution won't fail, and a warning will be printed to your console.

That way the calling method can decide if unexpected errors are visible for all users, by choosing the corresponding defer arguments.

The part of the discord-py-slash-command documentation where it talks about defer: https://discord-py-slash-command.readthedocs.io/en/stable/quickstart.html


推荐阅读