Skip to content
Open
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
35 changes: 22 additions & 13 deletions src/main/java/com/tumblr/jumblr/exceptions/JumblrException.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.ArrayList;
import java.util.List;

import com.tumblr.jumblr.types.JumblrError;
import org.scribe.model.Response;


Expand All @@ -17,7 +18,7 @@ public class JumblrException extends RuntimeException {

private final int responseCode;
private String message;
private List<String> errors;
private List<JumblrError> errors;

/**
* Instantiate a new JumblrException given a bad response to wrap
Expand Down Expand Up @@ -63,7 +64,7 @@ public String getMessage() {
* Get the errors returned from the API
* @return the errors (or null if none)
*/
public List<String> getErrors() {
public List<JumblrError> getErrors() {
return this.errors;
}

Expand All @@ -72,21 +73,29 @@ public List<String> getErrors() {
* @param object the parsed response object
*/
private void extractErrors(JsonObject object) {
JsonObject response;
JsonArray responseErrors;
try {
response = object.getAsJsonObject("response");
responseErrors = object.getAsJsonArray("errors");
} catch (ClassCastException ex) {
return; // response is non-object
return; // errors is non-array
}
if (response == null) { return; }

JsonArray e = response.getAsJsonArray("errors");
if (e == null) { return; }
if (responseErrors == null) { return; }

// Set the errors
errors = new ArrayList<String>(e.size());
for (int i = 0; i < e.size(); i++) {
errors.add(e.get(i).getAsString());
errors = new ArrayList<JumblrError>(responseErrors.size());
for (int i = 0; i < responseErrors.size(); i++) {
JsonElement errorElement = responseErrors.get(i);
JumblrError error = new JumblrError();
if (errorElement.isJsonObject()) {
JsonObject errorJson = errorElement.getAsJsonObject();
error.setTitle(errorJson.get("title").getAsString());
error.setCode(errorJson.get("code").getAsInt());
error.setDetail(errorJson.get("detail").getAsString());
}
else {
error.setDetail(errorElement.getAsString());
}
errors.add(error);
}
}

Expand All @@ -113,7 +122,7 @@ private void extractMessage(JsonObject object) {
}

// Otherwise set a default
this.message = "Unknown Error";
this.message = "Unknown JumblrError";
}

}
66 changes: 66 additions & 0 deletions src/main/java/com/tumblr/jumblr/types/JumblrError.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.tumblr.jumblr.types;

/**
* This class represents an error that comes back from an API response.
*
* Example response with an error:
* <code>
* {
* "meta": {
* "status": 404,
* "msg": "Not Found"
* },
* "response": [],
* "errors": [
* {
* "title": "Not Found",
* "code": 4012,
* "detail": "This Tumblr is only viewable within the Tumblr dashboard"
* }
* ]
* }
* </code>
* @author ndtreviv
*/
public class JumblrError {

private String title;
private Integer code;
private String detail;

/**
* Get the error title
* @return error title
*/
public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

/**
* Get the error code
* @return error code
*/
public Integer getCode() {
return code;
}

public void setCode(Integer code) {
this.code = code;
}

/**
* Get the error detail
* @return error detail
*/
public String getDetail() {
return detail;
}

public void setDetail(String detail) {
this.detail = detail;
}
}
105 changes: 105 additions & 0 deletions src/test/java/com/tumblr/jumblr/exceptions/JumblrExceptionTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package com.tumblr.jumblr.exceptions;

import com.tumblr.jumblr.types.JumblrError;
import org.junit.Test;
import org.scribe.model.Response;

import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

/**
* Tests for JumblrException
*/
public class JumblrExceptionTest {

@Test
public void extractsMultiTypeErrors() {
// given
String content = "{\n" +
" \"meta\": {\n" +
" \"status\": 404,\n" +
" \"msg\": \"Not Found\"\n" +
" },\n" +
" \"response\": [],\n" +
" \"errors\": [\n" +
" \"test\"," +
" {\n" +
" \"title\": \"Not Found\",\n" +
" \"code\": 4012,\n" +
" \"detail\": \"This Tumblr is only viewable within the Tumblr dashboard\"\n" +
" }\n" +
" ]\n" +
"}";

Response response = mock(Response.class);
when(response.getCode()).thenReturn(404);
when(response.getBody()).thenReturn(content);

// when
JumblrException exception = new JumblrException(response);

// then
List<JumblrError> errors = exception.getErrors();
assertNotNull(errors);
assertEquals("Found two errors", errors.size(), 2);
assertEquals("Found string error", "test", errors.get(0).getDetail());
assertEquals("Found object error title", "Not Found", errors.get(1).getTitle());
assertEquals("Found object error code", new Integer(4012), errors.get(1).getCode());
assertEquals("Found object error detail", "This Tumblr is only viewable within the Tumblr dashboard", errors.get(1).getDetail());
}

@Test
public void extractsErrorsWithEmptyArray() {
// given
String content = "{\n" +
" \"meta\": {\n" +
" \"status\": 404,\n" +
" \"msg\": \"Not Found\"\n" +
" },\n" +
" \"response\": [],\n" +
" \"errors\": []\n" +
"}";

Response response = mock(Response.class);
when(response.getCode()).thenReturn(200);
when(response.getBody()).thenReturn(content);

// when
JumblrException exception = new JumblrException(response);

// then
List<JumblrError> errors = exception.getErrors();
assertNotNull(errors);
assertEquals("Found no errors", errors.size(), 0);
}

@Test
public void errorExtractionDoesNotFailWithNull() {
// given
String content = "{\n" +
" \"meta\": {\n" +
" \"status\": 404,\n" +
" \"msg\": \"Not Found\"\n" +
" },\n" +
" \"response\": []" +
"}";

Response response = mock(Response.class);
when(response.getCode()).thenReturn(200);
when(response.getBody()).thenReturn(content);

// when
JumblrException exception = new JumblrException(response);

// then
List<JumblrError> errors = exception.getErrors();
assertNull(errors);
}

}