From b3126d7335dd3eefca53e3bcb39d2f87c86d1f0c Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 14 Apr 2026 12:59:13 +0000 Subject: [PATCH] fix: update stale Twitter URLs, extract error message constant, improve HMAC perf and code style - Replace 6 stale twitter.com/stripestatus URLs with status.stripe.com in user-facing error messages (HttpURLConnectionClient, StripeRequest, LiveStripeResponseGetter) - Extract duplicated IOException error message into ApiConnectionException.create() factory method to eliminate 6 copies of the same string across 3 files - Use StringBuilder instead of String concatenation in Webhook.Util.computeHmacSha256 to avoid O(n^2) copying - Replace .size() == 0 with .isEmpty() in Webhook and RequestTelemetry Co-Authored-By: Jason Kelley --- .../exception/ApiConnectionException.java | 19 +++++++++++++ .../stripe/net/HttpURLConnectionClient.java | 18 ++----------- .../stripe/net/LiveStripeResponseGetter.java | 9 +------ .../java/com/stripe/net/RequestTelemetry.java | 2 +- .../java/com/stripe/net/StripeRequest.java | 27 +++---------------- src/main/java/com/stripe/net/Webhook.java | 8 +++--- 6 files changed, 30 insertions(+), 53 deletions(-) diff --git a/src/main/java/com/stripe/exception/ApiConnectionException.java b/src/main/java/com/stripe/exception/ApiConnectionException.java index 62fb8b7fef0..a96e9b632a1 100644 --- a/src/main/java/com/stripe/exception/ApiConnectionException.java +++ b/src/main/java/com/stripe/exception/ApiConnectionException.java @@ -10,4 +10,23 @@ public ApiConnectionException(String message) { public ApiConnectionException(String message, Throwable e) { super(message, null, null, 0, e); } + + /** + * Creates an {@link ApiConnectionException} with a standard message for IO errors during API + * requests. + * + * @param url the base URL that the request was made to + * @param cause the underlying IOException + * @return the exception + */ + public static ApiConnectionException create(String url, Throwable cause) { + String message = + String.format( + "IOException during API request to Stripe (%s): %s " + + "Please check your internet connection and try again. If this problem persists," + + " you should check Stripe's service status at https://status.stripe.com," + + " or let us know at support@stripe.com.", + url, cause.getMessage()); + return new ApiConnectionException(message, cause); + } } diff --git a/src/main/java/com/stripe/net/HttpURLConnectionClient.java b/src/main/java/com/stripe/net/HttpURLConnectionClient.java index 8287b67d71d..747adc01081 100644 --- a/src/main/java/com/stripe/net/HttpURLConnectionClient.java +++ b/src/main/java/com/stripe/net/HttpURLConnectionClient.java @@ -45,14 +45,7 @@ public StripeResponseStream requestStream(StripeRequest request) throws ApiConne return new StripeResponseStream(responseCode, headers, responseStream); } catch (IOException e) { - throw new ApiConnectionException( - String.format( - "IOException during API request to Stripe (%s): %s " - + "Please check your internet connection and try again. If this problem persists," - + "you should check Stripe's service status at https://twitter.com/stripestatus," - + " or let us know at support@stripe.com.", - Stripe.getApiBase(), e.getMessage()), - e); + throw ApiConnectionException.create(Stripe.getApiBase(), e); } } @@ -69,14 +62,7 @@ public StripeResponse request(StripeRequest request) throws ApiConnectionExcepti try { return responseStream.unstream(); } catch (IOException e) { - throw new ApiConnectionException( - String.format( - "IOException during API request to Stripe (%s): %s " - + "Please check your internet connection and try again. If this problem persists," - + "you should check Stripe's service status at https://twitter.com/stripestatus," - + " or let us know at support@stripe.com.", - Stripe.getApiBase(), e.getMessage()), - e); + throw ApiConnectionException.create(Stripe.getApiBase(), e); } } diff --git a/src/main/java/com/stripe/net/LiveStripeResponseGetter.java b/src/main/java/com/stripe/net/LiveStripeResponseGetter.java index d422b17b792..2d0b9e3a3a2 100644 --- a/src/main/java/com/stripe/net/LiveStripeResponseGetter.java +++ b/src/main/java/com/stripe/net/LiveStripeResponseGetter.java @@ -181,14 +181,7 @@ public InputStream requestStream(ApiRequest apiRequest) throws StripeException { try { response = responseStream.unstream(); } catch (IOException e) { - throw new ApiConnectionException( - String.format( - "IOException during API request to Stripe (%s): %s " - + "Please check your internet connection and try again. If this problem persists," - + "you should check Stripe's service status at https://twitter.com/stripestatus," - + " or let us know at support@stripe.com.", - Stripe.getApiBase(), e.getMessage()), - e); + throw ApiConnectionException.create(Stripe.getApiBase(), e); } handleError(response, apiRequest.getApiMode()); } diff --git a/src/main/java/com/stripe/net/RequestTelemetry.java b/src/main/java/com/stripe/net/RequestTelemetry.java index db728c29602..4a936a5a886 100644 --- a/src/main/java/com/stripe/net/RequestTelemetry.java +++ b/src/main/java/com/stripe/net/RequestTelemetry.java @@ -74,7 +74,7 @@ public void maybeEnqueueMetrics( return; } - if (usage != null && usage.size() == 0) { + if (usage != null && usage.isEmpty()) { usage = null; } diff --git a/src/main/java/com/stripe/net/StripeRequest.java b/src/main/java/com/stripe/net/StripeRequest.java index 63dde82a3f6..43e694962c5 100644 --- a/src/main/java/com/stripe/net/StripeRequest.java +++ b/src/main/java/com/stripe/net/StripeRequest.java @@ -75,14 +75,7 @@ private StripeRequest( this.headers = buildHeaders(method, this.options, this.content, apiMode); this.apiMode = apiMode; } catch (IOException e) { - throw new ApiConnectionException( - String.format( - "IOException during API request to Stripe (%s): %s " - + "Please check your internet connection and try again. If this problem persists," - + "you should check Stripe's service status at https://twitter.com/stripestatus," - + " or let us know at support@stripe.com.", - Stripe.getApiBase(), e.getMessage()), - e); + throw ApiConnectionException.create(Stripe.getApiBase(), e); } } @@ -112,14 +105,7 @@ private StripeRequest( this.headers = buildHeaders(method, this.options, this.content, apiMode); this.apiMode = apiMode; } catch (IOException e) { - throw new ApiConnectionException( - String.format( - "IOException during API request to Stripe (%s): %s " - + "Please check your internet connection and try again. If this problem persists," - + "you should check Stripe's service status at https://twitter.com/stripestatus," - + " or let us know at support@stripe.com.", - Stripe.getApiBase(), e.getMessage()), - e); + throw ApiConnectionException.create(Stripe.getApiBase(), e); } } @@ -279,14 +265,7 @@ private static HttpContent buildContentFromString( } private static void handleIOException(IOException e) throws ApiConnectionException { - throw new ApiConnectionException( - String.format( - "IOException during API request to Stripe (%s): %s " - + "Please check your internet connection and try again. If this problem persists," - + "you should check Stripe's service status at https://twitter.com/stripestatus," - + " or let us know at support@stripe.com.", - Stripe.getApiBase(), e.getMessage()), - e); + throw ApiConnectionException.create(Stripe.getApiBase(), e); } private static HttpHeaders buildHeaders( diff --git a/src/main/java/com/stripe/net/Webhook.java b/src/main/java/com/stripe/net/Webhook.java index 09505f70873..0890e55e113 100644 --- a/src/main/java/com/stripe/net/Webhook.java +++ b/src/main/java/com/stripe/net/Webhook.java @@ -133,7 +133,7 @@ public static boolean verifyHeader( throw new SignatureVerificationException( "Unable to extract timestamp and signatures from header", sigHeader); } - if (signatures.size() == 0) { + if (signatures.isEmpty()) { throw new SignatureVerificationException( "No signatures found with expected scheme", sigHeader); } @@ -239,11 +239,11 @@ public static String computeHmacSha256(String key, String message) Mac hasher = Mac.getInstance("HmacSHA256"); hasher.init(new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256")); byte[] hash = hasher.doFinal(message.getBytes(StandardCharsets.UTF_8)); - String result = ""; + StringBuilder result = new StringBuilder(hash.length * 2); for (byte b : hash) { - result += Integer.toString((b & 0xff) + 0x100, 16).substring(1); + result.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1)); } - return result; + return result.toString(); } /**