Skip to content

Commit 47aa333

Browse files
Stmatedrstoyanchev
authored andcommitted
Lenient integer parsing in ResponseMapGraphQlResponse
See gh-849
1 parent d2eaf3c commit 47aa333

File tree

2 files changed

+52
-6
lines changed

2 files changed

+52
-6
lines changed

spring-graphql/src/main/java/org/springframework/graphql/client/ResponseMapGraphQlResponse.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616

1717
package org.springframework.graphql.client;
1818

19+
import java.math.BigInteger;
1920
import java.util.Collections;
2021
import java.util.List;
2122
import java.util.Map;
23+
import java.util.Objects;
2224
import java.util.stream.Collectors;
2325

2426
import graphql.ErrorClassification;
@@ -130,10 +132,25 @@ private static final class MapResponseError implements ResponseError {
130132
@SuppressWarnings("unchecked")
131133
private static List<SourceLocation> initLocations(Map<String, Object> errorMap) {
132134
return ((List<Map<String, Object>>) errorMap.getOrDefault("locations", Collections.emptyList())).stream()
133-
.map(map -> new SourceLocation((int) map.get("line"), (int) map.get("column"), (String) map.get("sourceName")))
135+
.map(map -> new SourceLocation(
136+
objectAsInt(map.get("line")),
137+
objectAsInt(map.get("column")),
138+
Objects.toString(map.get("sourceName"))
139+
))
134140
.collect(Collectors.toList());
135141
}
136142

143+
private static int objectAsInt(Object value) {
144+
145+
if (value instanceof BigInteger bigInteger) {
146+
return bigInteger.intValue();
147+
} else if (value instanceof Number number) {
148+
return number.intValue();
149+
} else {
150+
return -1;
151+
}
152+
}
153+
137154
@SuppressWarnings("unchecked")
138155
private static String initPath(Map<String, Object> errorMap) {
139156
List<Object> path = (List<Object>) errorMap.get("path");

spring-graphql/src/test/java/org/springframework/graphql/client/DefaultGraphQlClientResponseTests.java

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,18 @@
1616

1717
package org.springframework.graphql.client;
1818

19+
import graphql.language.SourceLocation;
20+
import java.io.IOException;
1921
import java.util.Arrays;
2022
import java.util.Collections;
2123
import java.util.List;
2224
import java.util.Map;
23-
import java.util.stream.Collectors;
2425

2526
import graphql.GraphQLError;
2627
import graphql.GraphqlErrorBuilder;
2728
import graphql.execution.ResultPath;
2829
import org.junit.jupiter.api.Test;
30+
import org.testcontainers.shaded.com.fasterxml.jackson.databind.DeserializationFeature;
2931
import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper;
3032

3133
import org.springframework.graphql.ResponseError;
@@ -136,27 +138,54 @@ void fieldErrors() {
136138
assertThat(errors.get(2).getPath()).isEqualTo("me.friends[0].name");
137139
}
138140

139-
private GraphQLError createError(@Nullable String errorPath, String message) {
141+
@Test
142+
void errorWithBigIntegerNumbers() throws IOException {
143+
144+
String path = "me.friends";
145+
146+
GraphQLError error0 = createError("/me", "fail-me", new SourceLocation(100, 100));
147+
148+
ObjectMapper objectMapper = new ObjectMapper().enable(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS);
149+
String error0string = objectMapper.writeValueAsString(error0);
150+
Map<?, ?> error0Map = objectMapper.readValue(error0string, Map.class);
151+
152+
List<?> list = List.of(error0Map);
153+
154+
ClientGraphQlResponse response = createResponse(Collections.singletonMap("errors", list));
155+
ClientResponseField field = response.field(path);
156+
157+
List<ResponseError> errors = field.getErrors();
158+
159+
assertThat(errors).hasSize(1);
160+
assertThat(errors.get(0).getPath()).isEqualTo("me");
161+
assertThat(errors.get(0).getLocations().get(0).getLine()).isEqualTo(100);
162+
assertThat(errors.get(0).getLocations().get(0).getColumn()).isEqualTo(100);
163+
}
164+
165+
private GraphQLError createError(@Nullable String errorPath, String message, SourceLocation... locations) {
140166
GraphqlErrorBuilder<?> builder = GraphqlErrorBuilder.newError().message(message);
141167
if (errorPath != null) {
142168
builder = builder.path(ResultPath.parse(errorPath));
143169
}
170+
if (locations.length > 0) {
171+
builder = builder.locations(List.of(locations));
172+
}
144173
return builder.build();
145174
}
146175

147176
private ClientResponseField getFieldOnDataResponse(String path, String dataJson) throws Exception {
148177
Map<?, ?> dataMap = mapper.readValue(dataJson, Map.class);
149-
ClientGraphQlResponse response = creatResponse(Collections.singletonMap("data", dataMap));
178+
ClientGraphQlResponse response = createResponse(Collections.singletonMap("data", dataMap));
150179
return response.field(path);
151180
}
152181

153182
private ClientResponseField getFieldOnErrorResponse(String path, GraphQLError... errors) {
154183
List<?> list = Arrays.stream(errors).map(GraphQLError::toSpecification).toList();
155-
ClientGraphQlResponse response = creatResponse(Collections.singletonMap("errors", list));
184+
ClientGraphQlResponse response = createResponse(Collections.singletonMap("errors", list));
156185
return response.field(path);
157186
}
158187

159-
private ClientGraphQlResponse creatResponse(Map<String, Object> responseMap) {
188+
private ClientGraphQlResponse createResponse(Map<String, Object> responseMap) {
160189
return new DefaultClientGraphQlResponse(
161190
new DefaultClientGraphQlRequest("{test}", null, Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap()),
162191
new ResponseMapGraphQlResponse(responseMap),

0 commit comments

Comments
 (0)