stripe / stripe-java

Java library for the Stripe API.
https://stripe.com
MIT License
791 stars 357 forks source link

API error shadowed by ClassCastException message if error is not a json object #1846

Open notfinch opened 1 month ago

notfinch commented 1 month ago

Describe the bug

Using some stripebased payments, when an unsuccessful response is resived, the "error" field in the body may be a string instead of a correct json object in raw response While parsing the error in the com.stripe.net.LiveStripeResponseGetter#handleApiError method, a ClassCastException error is thrown which is thrown out and is uninformative to the sdk consumer

To Reproduce

  1. Make any api call that returns a non json type error
  2. Get exception java.lang.ClassCastException: class com.google.gson.JsonPrimitive cannot be cast to class com.google.gson.JsonObject

Expected behavior

It is expected that any api call with an error will throw a StripeException or its child exception with a message from the api

Code snippets

No response

OS

all

Java version

21

stripe-java version

26.1.0

API version

2024-06-20

Additional context

try {
      JsonObject jsonObject =
          ApiResource.INTERNAL_GSON
              .fromJson(response.body(), JsonObject.class)
              .getAsJsonObject("error");
      error = ApiResource.deserializeStripeObject(jsonObject.toString(), StripeError.class, this);
    } catch (JsonSyntaxException e) {
      raiseMalformedJsonError(response.body(), response.code(), response.requestId(), e);
    }

The issue here getAsJsonObject("error") I think that just need to add ClassCastException to the catch block

remi-stripe commented 1 month ago

@notfinch it should not be possible for the error to be a string instead of a proper JSON object. If this happens this would be a bug on our end we'd need to fix. I have definitely seen us do this incorrectly in the past but we've always quickly fixed those when it happened.

Do you have a concrete example where this happened and what the raw response looked like?