Невозможно избавиться от "Исключения при получении данных (/{apiName})" в graphql-spqr-spring-boot-starter
Я использую библиотеку 'graphql-spqr-spring-boot-starter' версии 0.0.4 из 'io.leangen.graphql'. Я умею настраивать ошибки. См. Приведенный ниже код и снимок экрана для справки:
Модели:
@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
@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);
}
}
Настраиваемый класс исключения:
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;
}
}
Однако я не знаю, как избавиться от Exception while fetching data (/saveStudent)
как показано на скриншоте выше для message
поле. Я знаю, что мы можем иметьGraphQLExceptionHandler
класс, который реализует GraphQLErrorHandler (graphql-java-kickstart)
. Но какой вариант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;
}
}
Может ли кто-нибудь помочь мне, как я могу удалить это утверждение и отправить только конкретное сообщение?
1 ответ
Вы можете создать
Bean
и переопределить
DataFetcherExceptionHandler
. Чтобы переопределить его, вы также должны переопределить стратегию выполнения:
@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;
}
}