简体   繁体   English

无法摆脱 graphql-spqr-spring-boot-starter 中的“获取数据时异常(/{apiName})”

[英]Unable to get rid of 'Exception while fetching data(/{apiName})' in graphql-spqr-spring-boot-starter

I'm using 'graphql-spqr-spring-boot-starter' library version 0.0.4 of 'io.leangen.graphql'.我正在使用 'io.leangen.graphql' 的 'graphql-spqr-spring-boot-starter' 库版本 0.0.4。 I'm able to customize errors.我可以自定义错误。 See the below code and screenshot for reference:请参阅以下代码和屏幕截图以供参考:

Models:楷模:

@Getter
@Setter
@ToString
@Entity
@Accessors
public class Student {
    
    @Id 
    @GraphQLQuery(name = "id", description = "A Student's ID")
    private Long id;
    
    @GraphQLQuery(name = "name", description = "A student's name")
    private String name;    
    
    private String addr;

}

Service class:服务 class:

@Service
@GraphQLApi
public class StudentService{
    
    private final StudentRepository studentRepository;
    private final AddressRepository addressRepository;
    
    public StudentService(StudentRepository studentRepository, AddressRepository addressRepository) {
        this.addressRepository = addressRepository;
        this.studentRepository = studentRepository;
    }
    
    @GraphQLQuery(name = "allStudents")
    public List<Student> getAllStudents() {
        return studentRepository.findAll();
    }

    @GraphQLQuery(name = "student")
    public Optional<Student> getStudentById(@GraphQLArgument(name = "id") Long id) {
        if(studentRepository.findById(id) != null)
            return studentRepository.findById(id);
        throw new StudentNotFoundException("We were unable to find a student with the provided id", "id");
    }
    
    @GraphQLMutation(name = "saveStudent")
    public Student saveStudent(@GraphQLArgument(name = "student") Student student) {
        if(student.getId() == null)
            throw new NoIdException("Please provide an Id to create a Student entry.");
        return studentRepository.save(student);
    }
}

Customized Exception class:自定义异常 class:

import java.util.List;

import graphql.ErrorType;
import graphql.GraphQLError;
import graphql.language.SourceLocation;

public class NoIdException extends RuntimeException implements GraphQLError {
    
    private String noIdMsg;
    
    public NoIdException(String noIdMsg) {
        this.noIdMsg = noIdMsg;
    }

    @Override
    public List<SourceLocation> getLocations() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public ErrorType getErrorType() {
        // TODO Auto-generated method stub
        return ErrorType.ValidationError;
    }

    @Override
    public String getMessage() {
        // TODO Auto-generated method stub
        return noIdMsg;
    }
}

帖子图片

However, I'm not sure how to get rid of Exception while fetching data (/saveStudent) as seen on the above screenshot for the message field.但是,我不确定如何Exception while fetching data (/saveStudent)如上面message字段的屏幕截图所示。 I know we can have GraphQLExceptionHandler class which implements GraphQLErrorHandler (graphql-java-kickstart) .我知道我们可以拥有实现GraphQLExceptionHandler GraphQLErrorHandler (graphql-java-kickstart) But what is the option for sqpr-spring-boot-starter ?但是sqpr-spring-boot-starter的选项是什么?

import graphql.*;
import graphql.kickstart.execution.error.*;
import org.springframework.stereotype.*;

import java.util.*;
import java.util.stream.*;

@Component
public class GraphQLExceptionHandler 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;
    }
}

Could someone please help me how can I remove this statement and send just the specific message?有人可以帮助我如何删除此声明并仅发送特定消息吗?

You can create a Bean and override DataFetcherExceptionHandler .您可以创建一个Bean并覆盖DataFetcherExceptionHandler To override it, you have to override the execution strategy too:要覆盖它,您还必须覆盖执行策略:

@Bean
public GraphQL graphQL(GraphQLSchema schema) {
    return GraphQL.newGraphQL(schema)
            .queryExecutionStrategy(new AsyncExecutionStrategy(new CustomDataFetcherExceptionHandler()))
            .mutationExecutionStrategy(new AsyncSerialExecutionStrategy(new CustomDataFetcherExceptionHandler()))
            .build();
}

private static class CustomDataFetcherExceptionHandler implements DataFetcherExceptionHandler {

    @Override
    public DataFetcherExceptionHandlerResult onException(DataFetcherExceptionHandlerParameters handlerParameters) {
        Throwable exception = handlerParameters.getException();
        SourceLocation sourceLocation = handlerParameters.getSourceLocation();
        CustomExceptionWhileDataFetching error = new CustomExceptionWhileDataFetching(exception, sourceLocation);

        return DataFetcherExceptionHandlerResult.newResult().error(error).build();
    }
}

private static class CustomExceptionWhileDataFetching implements GraphQLError {

    private final String message;
    private final List<SourceLocation> locations;

    public CustomExceptionWhileDataFetching(Throwable exception, SourceLocation sourceLocation) {
        this.locations = Collections.singletonList(sourceLocation);
        this.message = exception.getMessage();
    }

    @Override
    public String getMessage() {
        return this.message;
    }

    @Override
    public List<SourceLocation> getLocations() {
        return this.locations;
    }

    @Override
    public ErrorClassification getErrorType() {
        return ErrorType.DataFetchingException;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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