Skip to content
This repository has been archived by the owner on Dec 19, 2023. It is now read-only.

Commit

Permalink
Merge pull request #616 from BlasiusSecundus/feature/fix-invalid-json…
Browse files Browse the repository at this point in the history
…-handling

fix(#524): return valid error even if request body is invalid
  • Loading branch information
oliemansm committed May 8, 2021
2 parents 06ecfed + 740491f commit 41b1626
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 3 deletions.
@@ -0,0 +1,42 @@
package graphql.kickstart.spring.webflux.boot;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import org.assertj.core.util.Files;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.test.web.reactive.server.WebTestClient;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class InvalidJsonRequestTest {

@Autowired private WebTestClient webTestClient;

@ParameterizedTest
@ValueSource(strings = {"\"false\":true", "not-a-json"})
@DisplayName("Should return valid response to a request with invalid JSON or non-JSON body.")
void testHandlingInvalidJsonRequest(String badRequestBody) throws IOException {
// GIVEN
final String expectedJson =
Files.contentOf(
new ClassPathResource("response-to-invalid-request.json").getFile(),
StandardCharsets.UTF_8);
// WHEN - THEN
webTestClient
.post()
.uri("/graphql")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(badRequestBody)
.exchange()
.expectStatus()
.isEqualTo(HttpStatus.OK)
.expectBody()
.json(expectedJson);
}
}
@@ -0,0 +1,9 @@
{
"errors": [
{
"message": "Bad request - invalid request body.",
"locations": []
}
],
"data": null
}
@@ -1,12 +1,15 @@
package graphql.kickstart.spring;

import graphql.ExecutionResultImpl;
import graphql.kickstart.execution.GraphQLObjectMapper;
import graphql.kickstart.execution.GraphQLRequest;
import graphql.kickstart.execution.error.GenericGraphQLError;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
Expand All @@ -20,8 +23,11 @@
import org.springframework.web.server.ServerWebExchange;

@RequiredArgsConstructor
@Slf4j
public abstract class AbstractGraphQLController {

private static final String INVALID_REQUEST_BODY_MESSAGE = "Bad request - invalid request body.";

private final GraphQLObjectMapper objectMapper;

@PostMapping(
Expand All @@ -34,13 +40,17 @@ public Object graphqlPOST(
@Nullable @RequestParam(value = "operationName", required = false) String operationName,
@Nullable @RequestParam(value = "variables", required = false) String variablesJson,
@Nullable @RequestBody(required = false) String body,
ServerWebExchange serverWebExchange)
throws IOException {
ServerWebExchange serverWebExchange) {

body = Optional.ofNullable(body).orElse("");

if (MediaType.APPLICATION_JSON.isCompatibleWith(contentType)) {
GraphQLRequest request = objectMapper.readGraphQLRequest(body);
GraphQLRequest request;
try {
request = objectMapper.readGraphQLRequest(body);
} catch (IOException e) {
return handleBodyParsingException(e, serverWebExchange);
}
if (request.getQuery() == null) {
request.setQuery("");
}
Expand Down Expand Up @@ -95,4 +105,11 @@ protected abstract Object executeRequest(
String operationName,
Map<String, Object> variables,
ServerWebExchange serverWebExchange);

protected Object handleBodyParsingException(
Exception exception, ServerWebExchange serverWebExchange) {
log.error("{} {}", INVALID_REQUEST_BODY_MESSAGE, exception.getMessage());
return objectMapper.createResultFromExecutionResult(
new ExecutionResultImpl(new GenericGraphQLError(INVALID_REQUEST_BODY_MESSAGE)));
}
}

0 comments on commit 41b1626

Please sign in to comment.