简体   繁体   中英

Error handling with graphql-java-tools and graphql-spring-boot-starter

How to handle errors in my graphQL API? I am using graphql-java-tools and graphql-spring-boot-starter. I created error handler but every time I get response 200 even when exception was thrown. Could you tell me how I should set error code eg 400 in response?

@Component
public class CustomGraphQLErrorHandler implements GraphQLErrorHandler {

    @Override
    public List<GraphQLError> processErrors(List<GraphQLError> list) {
        return list.stream().map(this::getNested).collect(Collectors.toList());
    }

    private GraphQLError getNested(GraphQLError error) {
        if (error instanceof ExceptionWhileDataFetching) {
            ExceptionWhileDataFetching exceptionError = (ExceptionWhileDataFetching) error;
            if (exceptionError.getException() instanceof GraphQLError) {
                return (GraphQLError) exceptionError.getException();
            }
        }
        return error;
    }
}

The GraphQL server returns an HTTP 200 when it can accept the request (the syntax is valid, the server is up...).

If an error occurs, it returns an 200 and fills the errors list in the response.

So, on client side, you will have:

  • Technical server errors, if the HTTP status is different from 200
  • Errors when handling the request (technical or not) if the HTTP status is 200 and the errors list is not empty
  • No error if the HTTP status is 200 and the errors list is not present (it should not be present and empty, according to the GraphQL spec)

You can try to throw some exceptions in your error handling method eg

package my.company.graphql.error;

import java.util.List;
import java.util.stream.Collectors;

import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ResponseStatusException;

import graphql.GraphQLError;
import graphql.GraphQLException;
import graphql.servlet.core.GraphQLErrorHandler;
import graphql.validation.ValidationError;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class GraphQLErrorHandlerImpl implements GraphQLErrorHandler {

    @Override
    public List<GraphQLError> processErrors(List<GraphQLError> graphQLErrors) {
        return graphQLErrors.stream().map(this::handleGraphQLError).collect(Collectors.toList());
    }

    private GraphQLError handleGraphQLError(GraphQLError error) {
        if (error instanceof GraphQLException) {
            throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "GraphQLException as GraphQLError...", (GraphQLException) error);
        } else if (error instanceof ValidationError){
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "ValidationError: " + error.getMessage());
        } else {
            log.error("Yet another GraphQLError...", error);
            return error;
        }
    }

}

...except you'll only get the 400 status code and nothing more in your response because Spring is not here to handle the thrown exceptions as you're talking with the GraphQL servlet (not the Spring one) at eg http://127.0.0.1:8080/graphql

Only in your log you should be able to see the stacktrace: (this is just an example with a validation error for an unused fragment in the GraphQL query)

[2020-09-23 15:59:34.382]-[080-exec-2]-[INFO ]-[g.s.AbstractGraphQLHttpServlet]: Bad POST request: parsing failed
org.springframework.web.server.ResponseStatusException: 400 BAD_REQUEST "ValidationError: Validation error of type UnusedFragment: Unused fragment someUnusedFragment"
    at my.company.graphql.error.GraphQLErrorHandlerImpl.handleGraphQLError(GraphQLErrorHandlerImpl.java:33) ~[classes/:na]

It's up to you to introduce a more complex handling of GraphQL errors, but that'll just be test & trial (as we've also done for quite some time...)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM