From 99348fce53b5a2dc3ec88709d858325b4b4665a2 Mon Sep 17 00:00:00 2001 From: Luck Date: Tue, 28 Apr 2020 13:29:09 +0100 Subject: [PATCH] Reply with more descriptive message when http requests fail --- .../commands/misc/ApplyEditsCommand.java | 19 ++++++++- .../common/commands/misc/TreeCommand.java | 20 ++++++++- .../common/commands/misc/VerboseCommand.java | 20 ++++++++- .../common/locale/message/Message.java | 9 +++- .../luckperms/common/treeview/TreeView.java | 10 ++--- .../common/verbose/VerboseListener.java | 10 ++--- .../common/web/AbstractHttpClient.java | 4 +- .../luckperms/common/web/BytebinClient.java | 6 +-- .../web/UnsuccessfulRequestException.java | 42 +++++++++++++++++++ .../lucko/luckperms/common/web/WebEditor.java | 13 ++++-- 10 files changed, 126 insertions(+), 27 deletions(-) create mode 100644 common/src/main/java/me/lucko/luckperms/common/web/UnsuccessfulRequestException.java diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/misc/ApplyEditsCommand.java b/common/src/main/java/me/lucko/luckperms/common/commands/misc/ApplyEditsCommand.java index 01365c885..482e69f89 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/misc/ApplyEditsCommand.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/misc/ApplyEditsCommand.java @@ -49,6 +49,7 @@ import me.lucko.luckperms.common.sender.Sender; import me.lucko.luckperms.common.util.DurationFormatter; import me.lucko.luckperms.common.util.Predicates; import me.lucko.luckperms.common.util.Uuids; +import me.lucko.luckperms.common.web.UnsuccessfulRequestException; import me.lucko.luckperms.common.web.WebEditor; import net.luckperms.api.actionlog.Action; @@ -57,6 +58,7 @@ import net.luckperms.api.event.cause.DeletionCause; import net.luckperms.api.model.data.DataType; import net.luckperms.api.node.Node; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; @@ -79,7 +81,22 @@ public class ApplyEditsCommand extends SingleCommand { return CommandResult.INVALID_ARGS; } - JsonObject data = WebEditor.readDataFromBytebin(plugin.getBytebin(), code); + JsonObject data; + try { + data = WebEditor.readDataFromBytebin(plugin.getBytebin(), code); + } catch (UnsuccessfulRequestException e) { + if (e.getResponse().code() == 403) { + Message.EDITOR_HTTP_FORBIDDEN_FAILURE.send(sender); + } else { + Message.EDITOR_HTTP_REQUEST_FAILURE.send(sender, e.getResponse().code(), e.getResponse().message()); + } + return CommandResult.STATE_ERROR; + } catch (IOException e) { + new RuntimeException("Error uploading data to bytebin", e).printStackTrace(); + Message.EDITOR_HTTP_UNKNOWN_FAILURE.send(sender); + return CommandResult.STATE_ERROR; + } + if (data == null) { Message.APPLY_EDITS_UNABLE_TO_READ.send(sender, code); return CommandResult.FAILURE; diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/misc/TreeCommand.java b/common/src/main/java/me/lucko/luckperms/common/commands/misc/TreeCommand.java index 272316e6f..178ab5df1 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/misc/TreeCommand.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/misc/TreeCommand.java @@ -39,6 +39,7 @@ import me.lucko.luckperms.common.sender.Sender; import me.lucko.luckperms.common.treeview.TreeView; import me.lucko.luckperms.common.util.Predicates; import me.lucko.luckperms.common.util.Uuids; +import me.lucko.luckperms.common.web.UnsuccessfulRequestException; import net.kyori.text.Component; import net.kyori.text.TextComponent; @@ -46,6 +47,7 @@ import net.kyori.text.event.ClickEvent; import net.kyori.text.event.HoverEvent; import net.kyori.text.format.TextColor; +import java.io.IOException; import java.util.List; import java.util.UUID; @@ -91,7 +93,23 @@ public class TreeCommand extends SingleCommand { Message.TREE_UPLOAD_START.send(sender); PermissionCache permissionData = user == null ? null : user.getCachedData().getPermissionData(plugin.getQueryOptionsForUser(user).orElse(plugin.getContextManager().getStaticQueryOptions())); - String id = view.uploadPasteData(plugin.getBytebin(), sender, user, permissionData); + + String id; + try { + id = view.uploadPasteData(plugin.getBytebin(), sender, user, permissionData); + } catch (UnsuccessfulRequestException e) { + if (e.getResponse().code() == 403) { + Message.GENERIC_HTTP_FORBIDDEN_FAILURE.send(sender); + } else { + Message.GENERIC_HTTP_REQUEST_FAILURE.send(sender, e.getResponse().code(), e.getResponse().message()); + } + return CommandResult.STATE_ERROR; + } catch (IOException e) { + new RuntimeException("Error uploading data to bytebin", e).printStackTrace(); + Message.GENERIC_HTTP_UNKNOWN_FAILURE.send(sender); + return CommandResult.STATE_ERROR; + } + String url = plugin.getConfiguration().get(ConfigKeys.TREE_VIEWER_URL_PATTERN) + id; Message.TREE_URL.send(sender); diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/misc/VerboseCommand.java b/common/src/main/java/me/lucko/luckperms/common/commands/misc/VerboseCommand.java index 355b9a958..115dd84da 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/misc/VerboseCommand.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/misc/VerboseCommand.java @@ -40,6 +40,7 @@ import me.lucko.luckperms.common.util.Predicates; import me.lucko.luckperms.common.verbose.InvalidFilterException; import me.lucko.luckperms.common.verbose.VerboseFilter; import me.lucko.luckperms.common.verbose.VerboseListener; +import me.lucko.luckperms.common.web.UnsuccessfulRequestException; import net.kyori.text.Component; import net.kyori.text.TextComponent; @@ -47,6 +48,7 @@ import net.kyori.text.event.ClickEvent; import net.kyori.text.event.HoverEvent; import net.kyori.text.format.TextColor; +import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -112,7 +114,23 @@ public class VerboseCommand extends SingleCommand { Message.VERBOSE_OFF.send(sender); } else { Message.VERBOSE_UPLOAD_START.send(sender); - String id = listener.uploadPasteData(plugin.getBytebin()); + + String id; + try { + id = listener.uploadPasteData(plugin.getBytebin()); + } catch (UnsuccessfulRequestException e) { + if (e.getResponse().code() == 403) { + Message.GENERIC_HTTP_FORBIDDEN_FAILURE.send(sender); + } else { + Message.GENERIC_HTTP_REQUEST_FAILURE.send(sender, e.getResponse().code(), e.getResponse().message()); + } + return CommandResult.STATE_ERROR; + } catch (IOException e) { + new RuntimeException("Error uploading data to bytebin", e).printStackTrace(); + Message.GENERIC_HTTP_UNKNOWN_FAILURE.send(sender); + return CommandResult.STATE_ERROR; + } + String url = plugin.getConfiguration().get(ConfigKeys.VERBOSE_VIEWER_URL_PATTERN) + id; Message.VERBOSE_RESULTS_URL.send(sender); diff --git a/common/src/main/java/me/lucko/luckperms/common/locale/message/Message.java b/common/src/main/java/me/lucko/luckperms/common/locale/message/Message.java index ac50bc726..1f7b3f0f5 100644 --- a/common/src/main/java/me/lucko/luckperms/common/locale/message/Message.java +++ b/common/src/main/java/me/lucko/luckperms/common/locale/message/Message.java @@ -142,6 +142,10 @@ public enum Message { TREE_EMPTY("&cUnable to generate tree. No results were found.", true), TREE_URL("&aPermission tree URL:", true), + GENERIC_HTTP_REQUEST_FAILURE("&cUnable to communicate with the web app. (response code &4{}&c, message='{}')", true), + GENERIC_HTTP_FORBIDDEN_FAILURE("&cUnable to communicate with the web app - '&4forbidden access&c' error &4403&3. You network provider or firewall (antivirus / content filter?) may have blocked access to the resource.", true), + GENERIC_HTTP_UNKNOWN_FAILURE("&cUnable to communicate with the web app. Check the console for errors.", true), + SEARCH_SEARCHING("&aSearching for users and groups with &bpermissions {}&a...", true), SEARCH_SEARCHING_MEMBERS("&aSearching for users and groups who inherit from &b{}&a...", true), SEARCH_RESULT("&aFound &b{}&a entries from &b{}&a users and &b{}&a groups.", true), @@ -163,9 +167,12 @@ public enum Message { EDITOR_NO_MATCH("&cUnable to open editor. No objects matched the desired type.", true), EDITOR_START("&7Preparing a new editor session. Please wait...", true), - EDITOR_UPLOAD_FAILURE("&cUnable to upload permission data to the editor.", true), EDITOR_URL("&aClick the link below to open the editor:", true), + EDITOR_HTTP_REQUEST_FAILURE("&cUnable to communicate with the editor. (response code &4{}&c, message='{}')", true), + EDITOR_HTTP_FORBIDDEN_FAILURE("&cUnable to communicate with the editor - '&4forbidden access&c' error &4403&3. You network provider or firewall (antivirus / content filter?) may have blocked access to the resource.", true), + EDITOR_HTTP_UNKNOWN_FAILURE("&cUnable to communicate with the editor. Check the console for errors.", true), + CHECK_RESULT("&aPermission check result on user &b{}&a for permission &b{}&a: &f{}", true), CREATE_SUCCESS("&b{}&a was successfully created.", true), diff --git a/common/src/main/java/me/lucko/luckperms/common/treeview/TreeView.java b/common/src/main/java/me/lucko/luckperms/common/treeview/TreeView.java index ec06cef74..d16cd0d4e 100644 --- a/common/src/main/java/me/lucko/luckperms/common/treeview/TreeView.java +++ b/common/src/main/java/me/lucko/luckperms/common/treeview/TreeView.java @@ -36,6 +36,7 @@ import me.lucko.luckperms.common.util.gson.JObject; import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; import me.lucko.luckperms.common.web.AbstractHttpClient; import me.lucko.luckperms.common.web.BytebinClient; +import me.lucko.luckperms.common.web.UnsuccessfulRequestException; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -130,7 +131,7 @@ public class TreeView { * @param checker the permission data instance to check against, or null * @return the id, or null */ - public String uploadPasteData(BytebinClient bytebin, Sender sender, User user, PermissionCache checker) { + public String uploadPasteData(BytebinClient bytebin, Sender sender, User user, PermissionCache checker) throws IOException, UnsuccessfulRequestException { // only paste if there is actually data here if (!hasData()) { throw new IllegalStateException(); @@ -184,12 +185,7 @@ public class TreeView { e.printStackTrace(); } - try { - return bytebin.postContent(bytesOut.toByteArray(), AbstractHttpClient.JSON_TYPE, false).key(); - } catch (IOException e) { - e.printStackTrace(); - return null; - } + return bytebin.postContent(bytesOut.toByteArray(), AbstractHttpClient.JSON_TYPE, false).key(); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/verbose/VerboseListener.java b/common/src/main/java/me/lucko/luckperms/common/verbose/VerboseListener.java index d77559341..a330c4562 100644 --- a/common/src/main/java/me/lucko/luckperms/common/verbose/VerboseListener.java +++ b/common/src/main/java/me/lucko/luckperms/common/verbose/VerboseListener.java @@ -42,6 +42,7 @@ import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; import me.lucko.luckperms.common.verbose.event.VerboseEvent; import me.lucko.luckperms.common.web.AbstractHttpClient; import me.lucko.luckperms.common.web.BytebinClient; +import me.lucko.luckperms.common.web.UnsuccessfulRequestException; import net.kyori.text.TextComponent; import net.kyori.text.event.HoverEvent; @@ -255,7 +256,7 @@ public class VerboseListener { * @param bytebin the bytebin instance to upload with * @return the url */ - public String uploadPasteData(BytebinClient bytebin) { + public String uploadPasteData(BytebinClient bytebin) throws IOException, UnsuccessfulRequestException { // retrieve variables String startDate = DATE_FORMAT.format(this.startTime); String endDate = DATE_FORMAT.format(Instant.now()); @@ -295,12 +296,7 @@ public class VerboseListener { e.printStackTrace(); } - try { - return bytebin.postContent(bytesOut.toByteArray(), AbstractHttpClient.JSON_TYPE, false).key(); - } catch (IOException e) { - e.printStackTrace(); - return null; - } + return bytebin.postContent(bytesOut.toByteArray(), AbstractHttpClient.JSON_TYPE, false).key(); } private static String getTristateColor(Tristate tristate) { diff --git a/common/src/main/java/me/lucko/luckperms/common/web/AbstractHttpClient.java b/common/src/main/java/me/lucko/luckperms/common/web/AbstractHttpClient.java index c40f59160..62b90255d 100644 --- a/common/src/main/java/me/lucko/luckperms/common/web/AbstractHttpClient.java +++ b/common/src/main/java/me/lucko/luckperms/common/web/AbstractHttpClient.java @@ -43,11 +43,11 @@ public class AbstractHttpClient { this.okHttp = okHttp; } - protected Response makeHttpRequest(Request request) throws IOException { + protected Response makeHttpRequest(Request request) throws IOException, UnsuccessfulRequestException { Response response = this.okHttp.newCall(request).execute(); if (!response.isSuccessful()) { response.close(); - throw new RuntimeException("Request was unsuccessful: " + response.code() + " - " + response.message()); + throw new UnsuccessfulRequestException(response); } return response; } diff --git a/common/src/main/java/me/lucko/luckperms/common/web/BytebinClient.java b/common/src/main/java/me/lucko/luckperms/common/web/BytebinClient.java index e95327048..265f61fc1 100644 --- a/common/src/main/java/me/lucko/luckperms/common/web/BytebinClient.java +++ b/common/src/main/java/me/lucko/luckperms/common/web/BytebinClient.java @@ -65,7 +65,7 @@ public class BytebinClient extends AbstractHttpClient { } @Override - public Response makeHttpRequest(Request request) throws IOException { + public Response makeHttpRequest(Request request) throws IOException, UnsuccessfulRequestException { return super.makeHttpRequest(request); } @@ -78,7 +78,7 @@ public class BytebinClient extends AbstractHttpClient { * @return the key of the resultant content * @throws IOException if an error occurs */ - public Content postContent(byte[] buf, MediaType contentType, boolean allowModification) throws IOException { + public Content postContent(byte[] buf, MediaType contentType, boolean allowModification) throws IOException, UnsuccessfulRequestException { RequestBody body = RequestBody.create(contentType, buf); Request.Builder requestBuilder = new Request.Builder() @@ -117,7 +117,7 @@ public class BytebinClient extends AbstractHttpClient { * @param contentType the type of the content * @throws IOException if an error occurs */ - public void modifyContent(Content existingContent, byte[] buf, MediaType contentType) throws IOException { + public void modifyContent(Content existingContent, byte[] buf, MediaType contentType) throws IOException, UnsuccessfulRequestException { if (!existingContent.modifiable) { throw new IllegalArgumentException("Existing content is not modifiable"); } diff --git a/common/src/main/java/me/lucko/luckperms/common/web/UnsuccessfulRequestException.java b/common/src/main/java/me/lucko/luckperms/common/web/UnsuccessfulRequestException.java new file mode 100644 index 000000000..c9ed18c4e --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/common/web/UnsuccessfulRequestException.java @@ -0,0 +1,42 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.lucko.luckperms.common.web; + +import okhttp3.Response; + +public class UnsuccessfulRequestException extends Exception { + + private final Response response; + + public UnsuccessfulRequestException(Response response) { + super("Request was unsuccessful: " + response.code() + " - " + response.message()); + this.response = response; + } + + public Response getResponse() { + return this.response; + } +} diff --git a/common/src/main/java/me/lucko/luckperms/common/web/WebEditor.java b/common/src/main/java/me/lucko/luckperms/common/web/WebEditor.java index 070035422..c235263c3 100644 --- a/common/src/main/java/me/lucko/luckperms/common/web/WebEditor.java +++ b/common/src/main/java/me/lucko/luckperms/common/web/WebEditor.java @@ -136,9 +136,16 @@ public final class WebEditor { String pasteId; try { pasteId = plugin.getBytebin().postContent(bytesOut.toByteArray(), AbstractHttpClient.JSON_TYPE, false).key(); + } catch (UnsuccessfulRequestException e) { + if (e.getResponse().code() == 403) { + Message.EDITOR_HTTP_FORBIDDEN_FAILURE.send(sender); + } else { + Message.EDITOR_HTTP_REQUEST_FAILURE.send(sender, e.getResponse().code(), e.getResponse().message()); + } + return CommandResult.STATE_ERROR; } catch (IOException e) { new RuntimeException("Error uploading data to bytebin", e).printStackTrace(); - Message.EDITOR_UPLOAD_FAILURE.send(sender); + Message.EDITOR_HTTP_UNKNOWN_FAILURE.send(sender); return CommandResult.STATE_ERROR; } @@ -156,7 +163,7 @@ public final class WebEditor { return CommandResult.SUCCESS; } - public static JsonObject readDataFromBytebin(BytebinClient bytebin, String id) { + public static JsonObject readDataFromBytebin(BytebinClient bytebin, String id) throws IOException, UnsuccessfulRequestException { Request request = new Request.Builder() .header("User-Agent", bytebin.getUserAgent()) .url(bytebin.getUrl() + id) @@ -174,8 +181,6 @@ public final class WebEditor { } } } - } catch (IOException e) { - throw new RuntimeException(e); } }