Skip to content

Commit

Permalink
Create an exception when receiving UNKNOWN_WEBHOOK in interaction hoo…
Browse files Browse the repository at this point in the history
…ks (#2621)
  • Loading branch information
freya022 committed Apr 6, 2024
1 parent 13abdcb commit 398c23d
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 7 deletions.
17 changes: 14 additions & 3 deletions src/main/java/net/dv8tion/jda/api/requests/Request.java
Expand Up @@ -138,15 +138,26 @@ public void onFailure(Response response)
{
if (response.code == 429)
{
onFailure(new RateLimitedException(route, response.retryAfter));
onRateLimited(response);
}
else
{
onFailure(ErrorResponseException.create(
ErrorResponse.fromJSON(response.optObject().orElse(null)), response));
onFailure(createErrorResponseException(response));
}
}

public void onRateLimited(Response response)
{
onFailure(new RateLimitedException(route, response.retryAfter));
}

@Nonnull
public ErrorResponseException createErrorResponseException(@Nonnull Response response)
{
return ErrorResponseException.create(
ErrorResponse.fromJSON(response.optObject().orElse(null)), response);
}

public void onFailure(Throwable failException)
{
if (done)
Expand Down
Expand Up @@ -39,6 +39,7 @@
import net.dv8tion.jda.api.interactions.InteractionHook;
import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.components.LayoutComponent;
import net.dv8tion.jda.api.requests.ErrorResponse;
import net.dv8tion.jda.api.requests.GatewayIntent;
import net.dv8tion.jda.api.requests.RestAction;
import net.dv8tion.jda.api.requests.Route;
Expand All @@ -51,7 +52,9 @@
import net.dv8tion.jda.api.utils.data.DataObject;
import net.dv8tion.jda.api.utils.messages.MessageEditData;
import net.dv8tion.jda.internal.JDAImpl;
import net.dv8tion.jda.internal.interactions.InteractionHookImpl;
import net.dv8tion.jda.internal.requests.CompletedRestAction;
import net.dv8tion.jda.internal.requests.ErrorMapper;
import net.dv8tion.jda.internal.requests.RestActionImpl;
import net.dv8tion.jda.internal.requests.restaction.AuditableRestActionImpl;
import net.dv8tion.jda.internal.requests.restaction.MessageEditActionImpl;
Expand Down Expand Up @@ -774,7 +777,9 @@ public AuditableRestAction<Void> delete()
if (isWebhookRequest())
{
Route.CompiledRoute route = Route.Webhooks.EXECUTE_WEBHOOK_DELETE.compile(webhook.getId(), webhook.getToken(), getId());
return new AuditableRestActionImpl<>(getJDA(), route);
final AuditableRestActionImpl<Void> action = new AuditableRestActionImpl<>(getJDA(), route);
action.setErrorMapper(getUnknownWebhookErrorMapper());
return action;
}

SelfUser self = getJDA().getSelfUser();
Expand Down Expand Up @@ -839,7 +844,9 @@ public AuditableRestAction<Void> suppressEmbeds(boolean suppressed)
newFlags &= ~suppressionValue;
DataObject body = DataObject.empty().put("flags", newFlags);

return new AuditableRestActionImpl<>(api, route, body);
final AuditableRestActionImpl<Void> action = new AuditableRestActionImpl<>(api, route, body);
action.setErrorMapper(getUnknownWebhookErrorMapper());
return action;
}

@Nonnull
Expand Down Expand Up @@ -980,8 +987,27 @@ private boolean isWebhookRequest()
@Nonnull
private MessageEditActionImpl editRequest()
{
return hasChannel()
final MessageEditActionImpl messageEditAction = hasChannel()
? new MessageEditActionImpl(getChannel(), getId())
: new MessageEditActionImpl(getJDA(), hasGuild() ? getGuild() : null, getChannelId(), getId());

messageEditAction.setErrorMapper(getUnknownWebhookErrorMapper());
return messageEditAction;
}

private ErrorMapper getUnknownWebhookErrorMapper()
{
if (!isWebhookRequest())
return null;

return (response, request, exception) ->
{
if (webhook instanceof InteractionHookImpl
&& !((InteractionHookImpl) webhook).isAck()
&& exception.getErrorResponse() == ErrorResponse.UNKNOWN_WEBHOOK)
return new IllegalStateException("Sending a webhook request requires the interaction to be acknowledged before expiration", exception);
else
return null;
};
}
}
31 changes: 31 additions & 0 deletions src/main/java/net/dv8tion/jda/internal/requests/ErrorMapper.java
@@ -0,0 +1,31 @@
/*
* Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.dv8tion.jda.internal.requests;

import net.dv8tion.jda.api.exceptions.ErrorResponseException;
import net.dv8tion.jda.api.requests.Request;
import net.dv8tion.jda.api.requests.Response;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

@FunctionalInterface
public interface ErrorMapper
{
@Nullable
Throwable apply(@Nonnull Response response, @Nonnull Request<?> request, @Nonnull ErrorResponseException exception);
}
Expand Up @@ -63,6 +63,7 @@ else if (t.getCause() != null)
private final Route.CompiledRoute route;
private final RequestBody data;
private final BiFunction<Response, Request<T>, T> handler;
private ErrorMapper errorMapper = null;

private boolean priority = false;
private long deadline = 0;
Expand Down Expand Up @@ -146,6 +147,11 @@ public RestActionImpl(JDA api, Route.CompiledRoute route, RequestBody data, BiFu
this.handler = handler;
}

public void setErrorMapper(ErrorMapper errorMapper)
{
this.errorMapper = errorMapper;
}

public RestActionImpl<T> priority()
{
priority = true;
Expand Down Expand Up @@ -277,8 +283,20 @@ public void handleResponse(Response response, Request<T> request)
{
if (response.isOk())
handleSuccess(response, request);
else if (response.isRateLimit())
request.onRateLimited(response);
else
request.onFailure(response);
{
final ErrorResponseException exception = request.createErrorResponseException(response);
final Throwable mappedThrowable = this.errorMapper != null
? this.errorMapper.apply(response, request, exception)
: null;

if (mappedThrowable != null)
request.onFailure(mappedThrowable);
else
request.onFailure(exception);
}
}

protected void handleSuccess(Response response, Request<T> request)
Expand Down

0 comments on commit 398c23d

Please sign in to comment.