From 2e5b8079fab18e83fee3ae7cc5233bb5b40f9908 Mon Sep 17 00:00:00 2001 From: joecqupt Date: Mon, 19 Oct 2026 20:59:32 +0800 Subject: [PATCH] core: Reject retryThrottling without maxTokens or tokenRatio clearly Both fields are required, but a missing one caused an NPE from Double.floatValue() with no hint of which field was absent. Check them explicitly, matching the "cannot be empty" messages used for the required retryPolicy and hedgingPolicy fields. --- .../io/grpc/internal/ServiceConfigUtil.java | 9 +++++--- .../grpc/internal/ServiceConfigUtilTest.java | 22 +++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/io/grpc/internal/ServiceConfigUtil.java b/core/src/main/java/io/grpc/internal/ServiceConfigUtil.java index 34d44f7f549..bf660d62b8d 100644 --- a/core/src/main/java/io/grpc/internal/ServiceConfigUtil.java +++ b/core/src/main/java/io/grpc/internal/ServiceConfigUtil.java @@ -112,9 +112,12 @@ static Throttle getThrottlePolicy(@Nullable Map serviceConfig) { return null; } - // TODO(dapengzhang0): check if this is null. - float maxTokens = JsonUtil.getNumberAsDouble(throttling, "maxTokens").floatValue(); - float tokenRatio = JsonUtil.getNumberAsDouble(throttling, "tokenRatio").floatValue(); + float maxTokens = checkNotNull( + JsonUtil.getNumberAsDouble(throttling, "maxTokens"), + "maxTokens cannot be empty").floatValue(); + float tokenRatio = checkNotNull( + JsonUtil.getNumberAsDouble(throttling, "tokenRatio"), + "tokenRatio cannot be empty").floatValue(); checkState(maxTokens > 0f, "maxToken should be greater than zero"); checkState(tokenRatio > 0f, "tokenRatio should be greater than zero"); return new Throttle(maxTokens, tokenRatio); diff --git a/core/src/test/java/io/grpc/internal/ServiceConfigUtilTest.java b/core/src/test/java/io/grpc/internal/ServiceConfigUtilTest.java index a49ae33f515..2ab53d92e81 100644 --- a/core/src/test/java/io/grpc/internal/ServiceConfigUtilTest.java +++ b/core/src/test/java/io/grpc/internal/ServiceConfigUtilTest.java @@ -114,6 +114,28 @@ public void unwrapLoadBalancingConfigList_failOnMalformedConfig() throws Excepti } } + @Test + public void getThrottlePolicy_failOnMissingMaxTokens() throws Exception { + String serviceConfig = "{\"retryThrottling\" : {\"tokenRatio\" : 0.1}}"; + try { + ServiceConfigUtil.getThrottlePolicy(checkObject(JsonParser.parse(serviceConfig))); + fail("Should throw"); + } catch (Exception e) { + assertThat(e).hasMessageThat().contains("maxTokens cannot be empty"); + } + } + + @Test + public void getThrottlePolicy_failOnMissingTokenRatio() throws Exception { + String serviceConfig = "{\"retryThrottling\" : {\"maxTokens\" : 10}}"; + try { + ServiceConfigUtil.getThrottlePolicy(checkObject(JsonParser.parse(serviceConfig))); + fail("Should throw"); + } catch (Exception e) { + assertThat(e).hasMessageThat().contains("tokenRatio cannot be empty"); + } + } + @SuppressWarnings("unchecked") private static List> checkObjectList(Object o) { return (List>) o;