Skip to content

Commit

Permalink
add ApiError model and TooManyRequestsException
Browse files Browse the repository at this point in the history
  • Loading branch information
saibotk committed Apr 25, 2019
1 parent 19a29dc commit 9d66dde
Show file tree
Hide file tree
Showing 13 changed files with 154 additions and 21 deletions.
63 changes: 63 additions & 0 deletions src/main/java/de/saibotk/jmaw/ApiError.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package de.saibotk.jmaw;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

/**
* Simple error model. This is sometimes returned by the API for requests that are invalid or eg. when the rate limit
* was exceeded.
*
* @author saibotk
* @since 1.0
*/
public class ApiError {

@SerializedName("error")
@Expose
private String error;

@SerializedName("errorMessage")
@Expose
private String errorMessage;

/**
* Returns the error name.
*
* @return name of the error.
* @since 1.0
*/
public String getError() {
return error;
}

/**
* Sets the error name.
* This will not modify anything on the Mojang account / API.
*
* @param error the error name.
* @since 1.0
*/
void setError(String error) {
this.error = error;
}

/**
* Returns the error message.
*
* @return error message.
* @since 1.0
*/
public String getErrorMessage() {
return errorMessage;
}

/**
* Sets the error message.
* This will not modify anything on the Mojang account / API.
* @param errorMessage error message.
* @since 1.0
*/
void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
}
26 changes: 25 additions & 1 deletion src/main/java/de/saibotk/jmaw/ApiResponseException.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package de.saibotk.jmaw;

import com.google.gson.GsonBuilder;
import okhttp3.ResponseBody;
import retrofit2.Response;

import java.io.IOException;
import java.util.Optional;

/**
* This represents an API exception, for example when the server responds with an HTTP 400 message.
Expand All @@ -12,10 +14,12 @@
* @author saibotk
* @since 1.0
*/
public class ApiResponseException extends IOException {
public class ApiResponseException extends Exception {

public final transient Response response;

private final transient ApiError errorResponse;

/**
* The ApiResponseException constructor will set the error message and the response associated with the exception.
* @param response the response associated to the exception.
Expand All @@ -24,6 +28,17 @@ public class ApiResponseException extends IOException {
ApiResponseException(Response response) {
super(response.code() + ": [" + response.message() + "]");
this.response = response;

ApiError parsedError = null;
try (ResponseBody body = response.errorBody()) {
if (body != null) {
String content = body.string();
parsedError = new GsonBuilder().create().fromJson(content, ApiError.class);
}
} catch (IOException e) {
e.printStackTrace();
}
this.errorResponse = parsedError;
}

/**
Expand All @@ -44,4 +59,13 @@ public ResponseBody getErrorBody() {
return response.errorBody();
}

/**
* Returns the API's response parsed as a {@link ApiError} object, if it contains the typical error and errorMessage fields.
*
* @return the parsed {@link ApiError} object.
* @since 1.0
*/
public Optional<ApiError> getApiError() {
return Optional.ofNullable(errorResponse);
}
}
6 changes: 5 additions & 1 deletion src/main/java/de/saibotk/jmaw/MojangAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,11 @@ private <T> Optional<T> request(Call<T> callToExecute, String url) throws ApiRes
if (response.isSuccessful()) {
return Optional.ofNullable(response.body());
} else {
throw new ApiResponseException(response);
ApiResponseException ex = new ApiResponseException(response);
if (ex.getApiError().isPresent() && ex.getApiError().get().getError().equals("TooManyRequestsException")) {
throw new TooManyRequestsException(response);
}
throw ex;
}
}
return Optional.empty();
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/de/saibotk/jmaw/PlayerProfile.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package de.saibotk.jmaw;

import java.util.List;
import java.util.Optional;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

import java.util.List;
import java.util.Optional;

/**
* This models the response for the Mojang API when querying for information on a specific player via
* {@link MojangAPI#getPlayerProfile(String)}.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package de.saibotk.jmaw;

import com.google.gson.*;
import java.util.Base64;

import java.lang.reflect.Type;
import java.util.Base64;

/**
* A TypeAdapter only implementing the {@link JsonDeserializer} interface since we will never send a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,16 @@

package de.saibotk.jmaw;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.*;
import com.google.gson.internal.Streams;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

/**
* Adapts values whose runtime type may differ from their declaration type. This
* is necessary when a field's type is not the same type that GSON should create
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/de/saibotk/jmaw/TooManyRequestsException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package de.saibotk.jmaw;

import retrofit2.Response;

/**
* This represents the TooManyRequestsException returned by the API.
*
* @author saibotk
* @since 1.0
*/
public class TooManyRequestsException extends ApiResponseException {

/**
* The TooManyRequestsException constructor will set the error message and the response associated with the exception.
*
* @param response the response associated to the exception.
* @since 1.0
*/
TooManyRequestsException(Response response) {
super(response);
}
}
1 change: 1 addition & 0 deletions src/test/java/de/saibotk/jmaw/APIStatusTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import org.junit.Test;

import static org.junit.Assert.*;

/**
Expand Down
3 changes: 2 additions & 1 deletion src/test/java/de/saibotk/jmaw/BlockedServersTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

import java.util.List;

import static org.junit.Assert.*;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;

/**
* Tests regarding the {@link MojangAPI#getBlockedServers()} method.
Expand Down
19 changes: 19 additions & 0 deletions src/test/java/de/saibotk/jmaw/PlayerProfileTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -206,4 +206,23 @@ public void testPlayerProfileResponseOnError() throws ApiResponseException {
// execute
classUnderTest.getPlayerProfile("4566e69fc90748ee8d71d7ba5aa00d20");
}

@Test public void testPlayerProfileResponseTooMany() {
// before
MojangAPI classUnderTest = new MojangAPI();

// execute
PlayerProfile pp1 = null;
PlayerProfile pp2 = null;
try {
pp1 = classUnderTest.getPlayerProfile("4566e69fc90748ee8d71d7ba5aa00d20").orElse(null);
pp2 = classUnderTest.getPlayerProfile("4566e69fc90748ee8d71d7ba5aa00d20").orElse(null);
} catch (ApiResponseException e) {
assertTrue(e instanceof TooManyRequestsException);
}

assertNotNull(pp1);
assertNull(pp2);

}
}
3 changes: 2 additions & 1 deletion src/test/java/de/saibotk/jmaw/SaleStatisticsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
import java.util.ArrayList;
import java.util.List;

import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

/**
* Tests regarding the {@link SaleStatistics} returned by the {@link MojangAPI#getSaleStatistics(List)} method.
Expand Down
4 changes: 3 additions & 1 deletion src/test/java/de/saibotk/jmaw/UUIDInfoTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import org.junit.Test;
import static org.junit.Assert.*;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

/**
* Tests regarding the {@link UUIDInfo} returned by the {@link MojangAPI#getUUIDInfo(String, long)} method.
Expand Down
3 changes: 2 additions & 1 deletion src/test/java/de/saibotk/jmaw/UsernamesToUUIDInfoTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
import java.util.ArrayList;
import java.util.List;

import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

/**
* Tests regarding the {@link UUIDInfo} returned by the {@link MojangAPI#getUUIDsForUsernames(List)} method.
Expand Down

0 comments on commit 9d66dde

Please sign in to comment.