Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Unknown Interaction error responses #2687

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,18 @@ private ErrorResponseException(ErrorResponse errorResponse, Response response, i
this.errorResponse = errorResponse;
this.code = code;
this.meaning = meaning;
this.schemaErrors = schemaErrors;
this.schemaErrors = Collections.unmodifiableList(schemaErrors);
}

private ErrorResponseException(String message, ErrorResponseException cause)
{
super(cause.code + ": " + message, cause);

this.response = cause.response;
this.errorResponse = cause.errorResponse;
this.code = cause.code;
this.meaning = cause.meaning;
this.schemaErrors = cause.schemaErrors;
}

/**
Expand Down Expand Up @@ -134,6 +145,11 @@ public List<SchemaError> getSchemaErrors()
return schemaErrors;
}

public static ErrorResponseException create(String message, ErrorResponseException cause)
{
return new ErrorResponseException(message, cause);
}

public static ErrorResponseException create(ErrorResponse errorResponse, Response response)
{
String meaning = errorResponse.getMeaning();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ public enum ErrorResponse
USER_NOT_CONNECTED( 40032, "Target user is not connected to voice."),
ALREADY_CROSSPOSTED( 40033, "This message has already been crossposted."),
APPLICATION_COMMAND_NAME_ALREADY_EXISTS( 40041, "An application command with that name already exists"),
INTERACTION_ALREADY_ACKNOWLEDGED( 40060, "Interaction has already been acknowledged"),
MISSING_ACCESS( 50001, "Missing Access"),
INVALID_ACCOUNT_TYPE( 50002, "Invalid Account Type"),
INVALID_DM_ACTION( 50003, "Cannot execute action on a DM channel"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@

package net.dv8tion.jda.internal.requests.restaction.interactions;

import net.dv8tion.jda.api.requests.Request;
import net.dv8tion.jda.api.requests.Response;
import net.dv8tion.jda.api.requests.RestAction;
import net.dv8tion.jda.api.requests.Route;
import net.dv8tion.jda.api.exceptions.ErrorResponseException;
import net.dv8tion.jda.api.requests.*;
import net.dv8tion.jda.api.requests.restaction.interactions.InteractionCallbackAction;
import net.dv8tion.jda.internal.interactions.InteractionImpl;
import net.dv8tion.jda.internal.requests.RestActionImpl;
Expand All @@ -36,6 +34,38 @@ public InteractionCallbackImpl(InteractionImpl interaction)
{
super(interaction.getJDA(), Route.Interactions.CALLBACK.compile(interaction.getId(), interaction.getToken()));
this.interaction = interaction;
setErrorMapper(this::handleUnknownInteraction);
}

private Throwable handleUnknownInteraction(Response response, Request<?> request, ErrorResponseException exception)
{
// While this error response has existed since at least 2022 (https://github.com/discord/discord-api-docs/pull/4484),
// Discord does not always report this error correctly and instead sends a 'UNKNOWN_INTERACTION'.
// That's why we also have a similar exception at the end of this method.
if (exception.getErrorResponse() == ErrorResponse.INTERACTION_ALREADY_ACKNOWLEDGED)
return ErrorResponseException.create(
"This interaction was acknowledged by another process running for the same bot.\n" +
"To resolve this, try stopping all current processes for the bot that could be responsible, or resetting your bot token.\n" +
"You can reset your token at https://discord.com/developers/applications/" + getJDA().getSelfUser().getApplicationId() + "/bot",
exception
);

// Time synchronization issues prevent us from checking the exact nature of the issue,
// and storing a local Instant would be invalid in case the WS thread is blocked,
// as it will be created when the thread is released.
// Send a message for both issues instead.
if (exception.getErrorResponse() == ErrorResponse.UNKNOWN_INTERACTION)
return ErrorResponseException.create(
"Failed to acknowledge this interaction, this can be due to 2 reasons:\n" +
"1. This interaction took longer than 3 seconds to be acknowledged, see https://jda.wiki/using-jda/troubleshooting/#the-interaction-took-longer-than-3-seconds-to-be-acknowledged\n" +
"2. This interaction could have been acknowledged by another process running for the same bot\n" +
"You can confirm this by checking if your bot replied, or the three dots in a button disappeared without saying 'This interaction failed', or you see '[Bot] is thinking...' for more than 3 seconds.\n" +
"To resolve this, try stopping all current processes for the bot that could be responsible, or resetting your bot token.\n" +
"You can reset your token at https://discord.com/developers/applications/" + getJDA().getSelfUser().getApplicationId() + "/bot",
exception
);

return null;
}

@Nonnull
Expand Down
Loading