diff --git a/src/main/java/com/stripe/net/LiveStripeResponseGetter.java b/src/main/java/com/stripe/net/LiveStripeResponseGetter.java index 0caba0cfd38..f11e94b87d1 100644 --- a/src/main/java/com/stripe/net/LiveStripeResponseGetter.java +++ b/src/main/java/com/stripe/net/LiveStripeResponseGetter.java @@ -6,7 +6,6 @@ import com.google.gson.JsonSyntaxException; import com.stripe.Stripe; import com.stripe.exception.*; -import com.stripe.exception.ApiKeyMissingException; import com.stripe.exception.oauth.InvalidClientException; import com.stripe.exception.oauth.InvalidGrantException; import com.stripe.exception.oauth.InvalidScopeException; @@ -289,22 +288,27 @@ private StripeError parseStripeError( } private void handleError(StripeResponse response, ApiMode apiMode) throws StripeException { - JsonObject responseBody = ApiResource.GSON.fromJson(response.body(), JsonObject.class); - - /* - OAuth errors are JSON objects where `error` is a string. In - contrast, in API errors, `error` is a hash with sub-keys. We use - this property to distinguish between OAuth and API errors. - */ - if (responseBody.has("error") && responseBody.get("error").isJsonPrimitive()) { - JsonPrimitive error = responseBody.getAsJsonPrimitive("error"); - if (error.isString()) { - handleOAuthError(response); + try { + /* + OAuth errors are JSON objects where `error` is a string. In + contrast, in API errors, `error` is a hash with sub-keys. We use + this property to distinguish between OAuth and API errors. + + Try to read the response body to see if it must be + */ + JsonObject responseBody = ApiResource.GSON.fromJson(response.body(), JsonObject.class); + if (responseBody.has("error") && responseBody.get("error").isJsonPrimitive()) { + JsonPrimitive error = responseBody.getAsJsonPrimitive("error"); + if (error.isString()) { + handleOAuthError(response); + } + } else if (apiMode == ApiMode.V2) { + handleV2ApiError(response); + } else { + handleV1ApiError(response); } - } else if (apiMode == ApiMode.V2) { - handleV2ApiError(response); - } else { - handleV1ApiError(response); + } catch (JsonSyntaxException e) { + throw makeMalformedJsonError(response.body(), response.code(), response.requestId(), e); } } diff --git a/src/test/java/com/stripe/functional/LiveStripeResponseGetterTest.java b/src/test/java/com/stripe/functional/LiveStripeResponseGetterTest.java index afc1f623ff4..8a470940027 100644 --- a/src/test/java/com/stripe/functional/LiveStripeResponseGetterTest.java +++ b/src/test/java/com/stripe/functional/LiveStripeResponseGetterTest.java @@ -63,4 +63,19 @@ public void testIdempotencyError() throws StripeException { }); assertThat(exception.getMessage(), CoreMatchers.containsString("idempotency")); } + + @Test + public void testErrorWithJsonSyntaxException() throws Exception { + HttpClient spy = Mockito.spy(new HttpURLConnectionClient()); + StripeResponseGetter srg = new LiveStripeResponseGetter(spy); + ApiResource.setGlobalResponseGetter(srg); + StripeResponse response = + new StripeResponse(400, HttpHeaders.of(Collections.emptyMap()), "I am not JSON :)"); + Mockito.doReturn(response).when(spy).requestWithRetries(Mockito.any()); + assertThrows( + StripeException.class, + () -> { + Subscription.retrieve("sub_123"); + }); + } }