diff --git a/google-api-client/pom.xml b/google-api-client/pom.xml index c06f356f2..2232616d4 100644 --- a/google-api-client/pom.xml +++ b/google-api-client/pom.xml @@ -159,6 +159,11 @@ com.google.http-client google-http-client + + com.google.code.gson + gson + test + com.google.protobuf protobuf-java diff --git a/google-api-client/src/main/java/com/google/api/client/googleapis/json/GoogleJsonError.java b/google-api-client/src/main/java/com/google/api/client/googleapis/json/GoogleJsonError.java index c0f0eb86b..dadd172fb 100644 --- a/google-api-client/src/main/java/com/google/api/client/googleapis/json/GoogleJsonError.java +++ b/google-api-client/src/main/java/com/google/api/client/googleapis/json/GoogleJsonError.java @@ -184,7 +184,7 @@ public ErrorInfo clone() { } } - public static class Details { + public static class Details extends GenericJson { @Key("@type") private String type; diff --git a/google-api-client/src/test/java/com/google/api/client/googleapis/json/GoogleJsonErrorTest.java b/google-api-client/src/test/java/com/google/api/client/googleapis/json/GoogleJsonErrorTest.java index c988804a6..380114aee 100644 --- a/google-api-client/src/test/java/com/google/api/client/googleapis/json/GoogleJsonErrorTest.java +++ b/google-api-client/src/test/java/com/google/api/client/googleapis/json/GoogleJsonErrorTest.java @@ -28,6 +28,7 @@ import com.google.api.client.testing.http.MockLowLevelHttpRequest; import com.google.api.client.testing.http.MockLowLevelHttpResponse; import java.io.InputStream; +import java.io.InputStreamReader; import junit.framework.TestCase; /** @@ -37,6 +38,7 @@ */ public class GoogleJsonErrorTest extends TestCase { + public static final com.google.gson.JsonParser JSON_PARSER = new com.google.gson.JsonParser(); static final JsonFactory FACTORY = new GsonFactory(); static final String ERROR = "{" @@ -93,6 +95,32 @@ public void testParse() throws Exception { assertEquals(ERROR, FACTORY.toString(errorResponse)); } + public void testParse_withMultipleErrorTypesInDetails() throws Exception { + InputStream errorResponseStream = + GoogleJsonErrorTest.class.getResourceAsStream( + "errorResponseWithMultipleTypesInDetails.json"); + + InputStream expectedParsedErrorResponse = + GoogleJsonErrorTest.class.getResourceAsStream( + "expectedParsedErrorWithMultipleTypesInDetails.json"); + + HttpTransport transport = + new ErrorTransport( + new MockLowLevelHttpResponse() + .setContent(errorResponseStream) + .setContentType(Json.MEDIA_TYPE) + .setStatusCode(HttpStatusCodes.STATUS_CODE_FORBIDDEN)); + HttpRequest request = + transport.createRequestFactory().buildGetRequest(HttpTesting.SIMPLE_GENERIC_URL); + request.setThrowExceptionOnExecuteError(false); + HttpResponse response = request.execute(); + com.google.api.client.googleapis.json.GoogleJsonError actualParsedErrorResponse = + com.google.api.client.googleapis.json.GoogleJsonError.parse(FACTORY, response); + assertEquals( + JSON_PARSER.parse(new InputStreamReader(expectedParsedErrorResponse)), + JSON_PARSER.parse(FACTORY.toString(actualParsedErrorResponse))); + } + public void testParse_withDetails() throws Exception { String DETAILS_ERROR = "{" @@ -122,7 +150,8 @@ public void testParse_withDetails() throws Exception { com.google.api.client.googleapis.json.GoogleJsonError errorResponse = com.google.api.client.googleapis.json.GoogleJsonError.parse(FACTORY, response); - assertEquals(DETAILS_ERROR, FACTORY.toString(errorResponse)); + assertEquals( + JSON_PARSER.parse(DETAILS_ERROR), JSON_PARSER.parse(FACTORY.toString(errorResponse))); assertNotNull(errorResponse.getDetails()); } @@ -166,7 +195,8 @@ public void testParse_withReasonInDetails() throws Exception { com.google.api.client.googleapis.json.GoogleJsonError errorResponse = com.google.api.client.googleapis.json.GoogleJsonError.parse(FACTORY, response); - assertEquals(DETAILS_ERROR, FACTORY.toString(errorResponse)); + assertEquals( + JSON_PARSER.parse(DETAILS_ERROR), JSON_PARSER.parse(FACTORY.toString(errorResponse))); assertNotNull(errorResponse.getDetails().get(2).getReason()); } } diff --git a/google-api-client/src/test/resources/com/google/api/client/googleapis/json/errorResponseWithMultipleTypesInDetails.json b/google-api-client/src/test/resources/com/google/api/client/googleapis/json/errorResponseWithMultipleTypesInDetails.json new file mode 100644 index 000000000..fc2826ac3 --- /dev/null +++ b/google-api-client/src/test/resources/com/google/api/client/googleapis/json/errorResponseWithMultipleTypesInDetails.json @@ -0,0 +1,65 @@ +{ + "error": { + "code": 400, + "message": "The template parameters are invalid.", + "status": "INVALID_ARGUMENT", + "details": [ + { + "@type": "type.googleapis.com/google.dataflow.v1beta3.InvalidTemplateParameters", + "reason": "TEST REASON 1", + "parameterViolations": [ + { + "parameter": "safeBrowsingApiKey", + "description": "Parameter didn't match regex '^[0-9a-zA-Z_]+$'" + } + ] + }, + { + "@type": "type.googleapis.com/google.rpc.DebugInfo", + "detail": "test detail" + }, + { + "@type": "type.googleapis.com/google.rpc.DebugInfo", + "reason": "test reason 2" + }, + { + "@type": "type.googleapis.com/google.rpc.BadRequest", + "fieldViolations": [ + { + "field": "language_code", + "description": "Field is required" + } + ] + }, + { + "@type": "type.googleapis.com/google.chrome.policy.v1.PolicyModificationErrorDetails", + "modificationErrors": [ + { + "policyTargetKey": { + "targetResource": "orgunits/03ph8a2z19ryqq8" + }, + "policySchema": "chrome.users.BrowserThemeColor", + "fieldErrors": [ + { + "field": "browserThemeColor", + "error": "Field is an invalid hex color. Only the numbers 0-9 and letters A-F are permitted." + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/google.mybusiness.v4.ValidationError", + "errorDetails": [ + { + "code": 3, + "field": "regular_hours.periods.close_time", + "message": "Time field must follow hh:mm format.", + "value": "25:00" + } + ] + } + ] + } +} + diff --git a/google-api-client/src/test/resources/com/google/api/client/googleapis/json/expectedParsedErrorWithMultipleTypesInDetails.json b/google-api-client/src/test/resources/com/google/api/client/googleapis/json/expectedParsedErrorWithMultipleTypesInDetails.json new file mode 100644 index 000000000..7cbf42e74 --- /dev/null +++ b/google-api-client/src/test/resources/com/google/api/client/googleapis/json/expectedParsedErrorWithMultipleTypesInDetails.json @@ -0,0 +1,63 @@ +{ + "code": 400, + "message": "The template parameters are invalid.", + "status": "INVALID_ARGUMENT", + "details": [ + { + "@type": "type.googleapis.com/google.dataflow.v1beta3.InvalidTemplateParameters", + "reason": "TEST REASON 1", + "parameterViolations": [ + { + "parameter": "safeBrowsingApiKey", + "description": "Parameter didn't match regex '^[0-9a-zA-Z_]+$'" + } + ] + }, + { + "@type": "type.googleapis.com/google.rpc.DebugInfo", + "detail": "test detail" + }, + { + "@type": "type.googleapis.com/google.rpc.DebugInfo", + "reason": "test reason 2" + }, + { + "@type": "type.googleapis.com/google.rpc.BadRequest", + "fieldViolations": [ + { + "field": "language_code", + "description": "Field is required" + } + ] + }, + { + "@type": "type.googleapis.com/google.chrome.policy.v1.PolicyModificationErrorDetails", + "modificationErrors": [ + { + "policyTargetKey": { + "targetResource": "orgunits/03ph8a2z19ryqq8" + }, + "policySchema": "chrome.users.BrowserThemeColor", + "fieldErrors": [ + { + "field": "browserThemeColor", + "error": "Field is an invalid hex color. Only the numbers 0-9 and letters A-F are permitted." + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/google.mybusiness.v4.ValidationError", + "errorDetails": [ + { + "code": 3, + "field": "regular_hours.periods.close_time", + "message": "Time field must follow hh:mm format.", + "value": "25:00" + } + ] + } + ] +} + diff --git a/pom.xml b/pom.xml index 69a910822..6a0f1b2b0 100644 --- a/pom.xml +++ b/pom.xml @@ -222,6 +222,12 @@ ${project.protobuf-java.version} test + + com.google.code.gson + gson + ${gson.version} + test + @@ -515,6 +521,7 @@ 4.0.3 2.5 false + 2.10