diff --git a/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/GraphQlAutoConfiguration.java b/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/GraphQlAutoConfiguration.java index fe84b7ec..88e5b3b6 100644 --- a/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/GraphQlAutoConfiguration.java +++ b/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/GraphQlAutoConfiguration.java @@ -38,6 +38,7 @@ import org.springframework.core.io.Resource; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.graphql.execution.DataFetcherExceptionResolver; import org.springframework.graphql.execution.GraphQlSource; +import org.springframework.graphql.execution.MissingSchemaException; import org.springframework.graphql.execution.RuntimeWiringConfigurer; /** @@ -71,7 +72,12 @@ public class GraphQlAutoConfiguration { .instrumentation(instrumentationsProvider.orderedStream().collect(Collectors.toList())); wiringConfigurers.orderedStream().forEach(builder::configureRuntimeWiring); sourceCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder)); - return builder.build(); + try { + return builder.build(); + } + catch (MissingSchemaException exc) { + throw new InvalidSchemaLocationsException(properties.getSchema().getLocations(), resourcePatternResolver, exc); + } } private List resolveSchemaResources(ResourcePatternResolver resolver, List schemaLocations) throws IOException { @@ -86,9 +92,6 @@ public class GraphQlAutoConfiguration { } } } - if (schemaResources.isEmpty()) { - throw new MissingSchemaException(schemaLocations, resolver); - } return schemaResources; } diff --git a/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/MissingSchemaException.java b/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/InvalidSchemaLocationsException.java similarity index 77% rename from graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/MissingSchemaException.java rename to graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/InvalidSchemaLocationsException.java index 94099a47..fd9d7a13 100644 --- a/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/MissingSchemaException.java +++ b/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/InvalidSchemaLocationsException.java @@ -21,18 +21,25 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import org.springframework.core.NestedRuntimeException; import org.springframework.core.io.support.ResourcePatternResolver; /** - * {@link MissingSchemaException} thrown when no schema can be found in the provided locations. + * {@link InvalidSchemaLocationsException} thrown when no schema file could be found in the provided locations. * * @author Brian Clozel + * @since 1.0.0 */ -public class MissingSchemaException extends RuntimeException { +public class InvalidSchemaLocationsException extends NestedRuntimeException { private final List schemaLocations; - public MissingSchemaException(List locations, ResourcePatternResolver resolver) { + public InvalidSchemaLocationsException(List locations, ResourcePatternResolver resolver) { + this(locations, resolver, null); + } + + public InvalidSchemaLocationsException(List locations, ResourcePatternResolver resolver, Throwable cause) { + super("No schema file could be found in the provided locations.", cause); List providedLocations = new ArrayList<>(); for (String location : locations) { try { diff --git a/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/MissingSchemaExceptionFailureAnalyzer.java b/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/InvalidSchemaLocationsExceptionFailureAnalyzer.java similarity index 78% rename from graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/MissingSchemaExceptionFailureAnalyzer.java rename to graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/InvalidSchemaLocationsExceptionFailureAnalyzer.java index 9cfbf84d..f740438e 100644 --- a/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/MissingSchemaExceptionFailureAnalyzer.java +++ b/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/InvalidSchemaLocationsExceptionFailureAnalyzer.java @@ -21,17 +21,17 @@ import org.springframework.boot.diagnostics.FailureAnalysis; /** * An implementation of {@link AbstractFailureAnalyzer} to analyze failures caused by - * {@link MissingSchemaException}. + * {@link InvalidSchemaLocationsException}. * * @author Brian Clozel */ -class MissingSchemaExceptionFailureAnalyzer extends AbstractFailureAnalyzer { +class InvalidSchemaLocationsExceptionFailureAnalyzer extends AbstractFailureAnalyzer { @Override - protected FailureAnalysis analyze(Throwable rootFailure, MissingSchemaException cause) { + protected FailureAnalysis analyze(Throwable rootFailure, InvalidSchemaLocationsException cause) { String message = "Could not find any GraphQL schema file under configured locations."; StringBuilder action = new StringBuilder("Check that the following locations contain schema files: " + System.lineSeparator()); - for (MissingSchemaException.SchemaLocation schemaLocation : cause.getSchemaLocations()) { + for (InvalidSchemaLocationsException.SchemaLocation schemaLocation : cause.getSchemaLocations()) { action.append(String.format("- '%s' (%s)" + System.lineSeparator(), schemaLocation.getUri(), schemaLocation.getLocation())); } return new FailureAnalysis(message, action.toString(), cause); diff --git a/graphql-spring-boot-starter/src/main/resources/META-INF/spring.factories b/graphql-spring-boot-starter/src/main/resources/META-INF/spring.factories index 937f2d96..6b72dc70 100644 --- a/graphql-spring-boot-starter/src/main/resources/META-INF/spring.factories +++ b/graphql-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -11,7 +11,7 @@ org.springframework.graphql.boot.data.GraphQlWebFluxQuerydslAutoConfiguration # Failure Analyzers org.springframework.boot.diagnostics.FailureAnalyzer=\ -org.springframework.graphql.boot.MissingSchemaExceptionFailureAnalyzer +org.springframework.graphql.boot.InvalidSchemaLocationsExceptionFailureAnalyzer # Spring Test @AutoConfigureGraphQlTester org.springframework.graphql.boot.test.tester.AutoConfigureGraphQlTester=\ diff --git a/graphql-spring-boot-starter/src/test/java/org/springframework/graphql/boot/GraphQlAutoConfigurationTests.java b/graphql-spring-boot-starter/src/test/java/org/springframework/graphql/boot/GraphQlAutoConfigurationTests.java index e5a7bf82..5f47a0b5 100644 --- a/graphql-spring-boot-starter/src/test/java/org/springframework/graphql/boot/GraphQlAutoConfigurationTests.java +++ b/graphql-spring-boot-starter/src/test/java/org/springframework/graphql/boot/GraphQlAutoConfigurationTests.java @@ -25,6 +25,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.graphql.execution.GraphQlSource; +import org.springframework.graphql.execution.MissingSchemaException; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultGraphQlSourceBuilder.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultGraphQlSourceBuilder.java index 9129f4e3..0005d9a2 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultGraphQlSourceBuilder.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultGraphQlSourceBuilder.java @@ -103,7 +103,7 @@ class DefaultGraphQlSourceBuilder implements GraphQlSource.Builder { public GraphQlSource build() { TypeDefinitionRegistry registry = this.schemaResources.stream() .map(this::parseSchemaResource).reduce(TypeDefinitionRegistry::merge) - .orElseThrow(() -> new IllegalArgumentException("'schemaResources' should not be empty")); + .orElseThrow(MissingSchemaException::new); RuntimeWiring.Builder runtimeWiringBuilder = RuntimeWiring.newRuntimeWiring(); this.runtimeWiringConfigurers.forEach(configurer -> configurer.configure(runtimeWiringBuilder)); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/MissingSchemaException.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/MissingSchemaException.java new file mode 100644 index 00000000..a0a52370 --- /dev/null +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/MissingSchemaException.java @@ -0,0 +1,32 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.graphql.execution; + +import org.springframework.core.NestedRuntimeException; + +/** + * Indicates that no GraphQL schema definition was configured on the {@link GraphQlSource.Builder}. + * + * @author Brian Clozel + * @since 1.0.0 + */ +public class MissingSchemaException extends NestedRuntimeException { + + public MissingSchemaException() { + super("No GraphQL schema definition was configured."); + } +}