From 4b1f8beb977f6425d63a1a05e6af722be23255b3 Mon Sep 17 00:00:00 2001 From: Sollace Date: Tue, 9 Apr 2019 13:41:33 +0200 Subject: [PATCH] Improve network error handling for skin servers --- .../voxelmodpack/hdskins/HDSkinManager.java | 2 +- .../voxelmodpack/hdskins/SkinUploader.java | 13 +++++++ .../hdskins/server/BethlehemSkinServer.java | 5 ++- .../hdskins/server/HttpException.java | 37 +++++++++++++++++++ .../hdskins/server/LegacySkinServer.java | 9 +++-- .../hdskins/server/SkinServer.java | 4 +- .../hdskins/server/ValhallaSkinServer.java | 2 +- 7 files changed, 62 insertions(+), 10 deletions(-) create mode 100644 src/hdskins/java/com/voxelmodpack/hdskins/server/HttpException.java diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java index b21b8e8c..761a29e2 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java @@ -71,7 +71,7 @@ import javax.annotation.Nullable; public final class HDSkinManager implements IResourceManagerReloadListener { - private static final Logger logger = LogManager.getLogger(); + public static final Logger logger = LogManager.getLogger(); public static final ExecutorService skinUploadExecutor = Executors.newSingleThreadExecutor(); public static final ExecutorService skinDownloadExecutor = Executors.newFixedThreadPool(8); diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/SkinUploader.java b/src/hdskins/java/com/voxelmodpack/hdskins/SkinUploader.java index 9fa67f10..551336ff 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/SkinUploader.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/SkinUploader.java @@ -17,6 +17,7 @@ import com.mumfrey.liteloader.util.log.LiteLoaderLogger; import com.voxelmodpack.hdskins.gui.EntityPlayerModel; import com.voxelmodpack.hdskins.gui.Feature; import com.voxelmodpack.hdskins.resources.PreviewTextureManager; +import com.voxelmodpack.hdskins.server.HttpException; import com.voxelmodpack.hdskins.server.SkinServer; import com.voxelmodpack.hdskins.server.SkinUpload; import com.voxelmodpack.hdskins.util.MoreHttpResponses; @@ -224,6 +225,18 @@ public class SkinUploader implements Closeable { offline = true; } else if (throwable instanceof AuthenticationException) { throttlingNeck = true; + } else if (throwable instanceof HttpException) { + HttpException ex = (HttpException)throwable; + + HDSkinManager.logger.error(ex.getReasonPhrase(), ex); + + int code = ex.getStatusCode(); + + if (code >= 500) { + setError(String.format("A fatal server error has ocurred (check logs for details): \n%s", ex.getReasonPhrase())); + } else if (code >= 400 && code != 403 && code != 404) { + setError(ex.getReasonPhrase()); + } } else { setError(throwable.toString()); } diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/server/BethlehemSkinServer.java b/src/hdskins/java/com/voxelmodpack/hdskins/server/BethlehemSkinServer.java index 0569d146..c3ca7a73 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/server/BethlehemSkinServer.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/server/BethlehemSkinServer.java @@ -32,7 +32,7 @@ public class BethlehemSkinServer implements SkinServer { public MinecraftTexturesPayload loadProfileData(GameProfile profile) throws IOException { try (MoreHttpResponses response = new NetClient("GET", getPath(profile)).send()) { if (!response.ok()) { - throw new IOException(response.getResponse().getStatusLine().getReasonPhrase()); + throw new HttpException(response.getResponse()); } return response.json(MinecraftTexturesPayload.class); @@ -53,8 +53,9 @@ public class BethlehemSkinServer implements SkinServer { try (MoreHttpResponses response = client.send()) { if (!response.ok()) { - throw new IOException(response.text()); + throw new HttpException(response.getResponse()); } + return new SkinUploadResponse(response.text()); } } diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/server/HttpException.java b/src/hdskins/java/com/voxelmodpack/hdskins/server/HttpException.java new file mode 100644 index 00000000..656a6eed --- /dev/null +++ b/src/hdskins/java/com/voxelmodpack/hdskins/server/HttpException.java @@ -0,0 +1,37 @@ +package com.voxelmodpack.hdskins.server; + +import org.apache.http.HttpResponse; +import org.apache.http.StatusLine; + +import java.io.IOException; + +public class HttpException extends IOException { + private static final long serialVersionUID = -6168434367054139332L; + + private final String reason; + + private final int statusCode; + + public HttpException(HttpResponse response) { + this(response.getStatusLine()); + } + + public HttpException(StatusLine status) { + this(status.getReasonPhrase(), status.getStatusCode(), null); + } + + public HttpException(String reason, int statusCode, Throwable cause) { + super("(" + statusCode + ") " + reason, cause); + + this.reason = reason; + this.statusCode = statusCode; + } + + public String getReasonPhrase() { + return reason; + } + + public int getStatusCode() { + return statusCode; + } +} diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/server/LegacySkinServer.java b/src/hdskins/java/com/voxelmodpack/hdskins/server/LegacySkinServer.java index f66897d3..cc9f3382 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/server/LegacySkinServer.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/server/LegacySkinServer.java @@ -83,7 +83,7 @@ public class LegacySkinServer implements SkinServer { Map map = builder.build(); if (map.isEmpty()) { - throw new IOException(String.format("No textures found for %s at %s", profile, this.address)); + throw new HttpException(String.format("No textures found for %s at %s", profile, this.address), 404, null); } return TexturesPayloadBuilder.createTexturesPayload(profile, map); } @@ -91,7 +91,7 @@ public class LegacySkinServer implements SkinServer { private MinecraftProfileTexture loadProfileTexture(GameProfile profile, String url) throws IOException { try (MoreHttpResponses resp = MoreHttpResponses.execute(HDSkinManager.httpClient, new HttpHead(url))) { if (!resp.ok()) { - throw new IOException("Bad response code: " + resp.getResponseCode() + ". URL: " + url); + throw new HttpException(resp.getResponse()); } logger.debug("Found skin for {} at {}", profile.getName(), url); @@ -124,14 +124,15 @@ public class LegacySkinServer implements SkinServer { client.putFile(upload.getType().toString().toLowerCase(Locale.US), "image/png", upload.getImage()); } - String response = client.send().text(); + MoreHttpResponses resp = client.send(); + String response = resp.text(); if (response.startsWith("ERROR: ")) { response = response.substring(7); } if (!response.equalsIgnoreCase("OK") && !response.endsWith("OK")) { - throw new IOException(response); + throw new HttpException(response, resp.getResponseCode(), null); } return new SkinUploadResponse(response); diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/server/SkinServer.java b/src/hdskins/java/com/voxelmodpack/hdskins/server/SkinServer.java index 8b3552bd..ac99dd03 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/server/SkinServer.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/server/SkinServer.java @@ -41,7 +41,7 @@ public interface SkinServer extends Exposable { * * @return The parsed server response as a textures payload. * - * @throws IOException If any authenticaiton or network error occurs. + * @throws IOException If any authentication or network error occurs. */ MinecraftTexturesPayload loadProfileData(GameProfile profile) throws IOException; @@ -52,7 +52,7 @@ public interface SkinServer extends Exposable { * * @return A server response object. * - * @throws IOException + * @throws IOException If any authentication or network error occurs. * @throws AuthenticationException */ SkinUploadResponse performSkinUpload(SkinUpload upload) throws IOException, AuthenticationException; diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/server/ValhallaSkinServer.java b/src/hdskins/java/com/voxelmodpack/hdskins/server/ValhallaSkinServer.java index 63f2b698..5d82e102 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/server/ValhallaSkinServer.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/server/ValhallaSkinServer.java @@ -46,7 +46,7 @@ public class ValhallaSkinServer implements SkinServer { return response.unwrapAsJson(MinecraftTexturesPayload.class); } - throw new IOException("Server sent non-ok response code: " + response.getResponseCode()); + throw new HttpException(response.getResponse()); } }