Skip to content

Commit 4238a16

Browse files
authored
A default implementation of DataFetcherExceptionHandler.onException (#2614)
* A default implementation of DataFetcherExceptionHandler.onException * Weird Groovy bug * Fixed up some tests * Fixed the latest test
1 parent 399284f commit 4238a16

File tree

6 files changed

+54
-10
lines changed

6 files changed

+54
-10
lines changed

src/main/java/graphql/execution/DataFetcherExceptionHandler.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ public interface DataFetcherExceptionHandler {
2727
* version
2828
*/
2929
@Deprecated
30-
DataFetcherExceptionHandlerResult onException(DataFetcherExceptionHandlerParameters handlerParameters);
30+
default DataFetcherExceptionHandlerResult onException(DataFetcherExceptionHandlerParameters handlerParameters) {
31+
return SimpleDataFetcherExceptionHandler.defaultImpl.onException(handlerParameters);
32+
}
3133

3234
/**
3335
* When an exception occurs during a call to a {@link DataFetcher} then this handler

src/main/java/graphql/execution/SimpleDataFetcherExceptionHandler.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import graphql.util.LogKit;
77
import org.slf4j.Logger;
88

9+
import java.util.concurrent.CompletableFuture;
910
import java.util.concurrent.CompletionException;
1011

1112
/**
@@ -17,6 +18,8 @@ public class SimpleDataFetcherExceptionHandler implements DataFetcherExceptionHa
1718

1819
private static final Logger logNotSafe = LogKit.getNotPrivacySafeLogger(SimpleDataFetcherExceptionHandler.class);
1920

21+
static final SimpleDataFetcherExceptionHandler defaultImpl = new SimpleDataFetcherExceptionHandler();
22+
2023
@Override
2124
public DataFetcherExceptionHandlerResult onException(DataFetcherExceptionHandlerParameters handlerParameters) {
2225
Throwable exception = unwrap(handlerParameters.getException());
@@ -29,9 +32,15 @@ public DataFetcherExceptionHandlerResult onException(DataFetcherExceptionHandler
2932
return DataFetcherExceptionHandlerResult.newResult().error(error).build();
3033
}
3134

35+
@Override
36+
public CompletableFuture<DataFetcherExceptionHandlerResult> handleException(DataFetcherExceptionHandlerParameters handlerParameters) {
37+
return CompletableFuture.completedFuture(onException(handlerParameters));
38+
}
39+
3240
/**
3341
* Called to log the exception - a subclass could choose to something different in logging terms
34-
* @param error the graphql error
42+
*
43+
* @param error the graphql error
3544
* @param exception the exception that happened
3645
*/
3746
protected void logException(ExceptionWhileDataFetching error, Throwable exception) {

src/test/groovy/graphql/GraphQLTest.groovy

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import graphql.collect.ImmutableKit
66
import graphql.execution.AsyncExecutionStrategy
77
import graphql.execution.AsyncSerialExecutionStrategy
88
import graphql.execution.DataFetcherExceptionHandler
9+
import graphql.execution.DataFetcherExceptionHandlerParameters
10+
import graphql.execution.DataFetcherExceptionHandlerResult
911
import graphql.execution.DataFetcherResult
1012
import graphql.execution.ExecutionContext
1113
import graphql.execution.ExecutionId
@@ -1156,16 +1158,23 @@ many lines''']
11561158
er.data["f"] == "hi"
11571159
}
11581160
1161+
11591162
def "can set default fetcher exception handler"() {
1163+
1164+
11601165
def sdl = 'type Query { f : String } '
11611166
11621167
DataFetcher df = { env ->
11631168
throw new RuntimeException("BANG!")
11641169
}
11651170
def capturedMsg = null
1166-
def exceptionHandler = { params ->
1167-
capturedMsg = params.exception.getMessage()
1168-
} as DataFetcherExceptionHandler
1171+
def exceptionHandler = new DataFetcherExceptionHandler() {
1172+
@Override
1173+
CompletableFuture<DataFetcherExceptionHandlerResult> handleException(DataFetcherExceptionHandlerParameters params) {
1174+
capturedMsg = params.exception.getMessage()
1175+
return CompletableFuture.completedFuture(DataFetcherExceptionHandlerResult.newResult().build())
1176+
}
1177+
}
11691178
def schema = TestUtil.schema(sdl, [Query: [f: df]])
11701179
def graphQL = GraphQL.newGraphQL(schema).defaultDataFetcherExceptionHandler(exceptionHandler).build()
11711180
when:

src/test/groovy/graphql/execution/DataFetcherExceptionHandlerTest.groovy

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,11 @@ class DataFetcherExceptionHandlerTest extends Specification {
5757
def "integration test to prove custom error handle can be made"() {
5858
DataFetcherExceptionHandler handler = new DataFetcherExceptionHandler() {
5959
@Override
60-
DataFetcherExceptionHandlerResult onException(DataFetcherExceptionHandlerParameters handlerParameters) {
60+
CompletableFuture<DataFetcherExceptionHandlerResult> handleException(DataFetcherExceptionHandlerParameters handlerParameters) {
6161
def msg = "The thing went " + handlerParameters.getException().getMessage()
62-
return DataFetcherExceptionHandlerResult.newResult().error(new CustomError(msg, handlerParameters.getSourceLocation())).build()
62+
return CompletableFuture.completedFuture(
63+
DataFetcherExceptionHandlerResult.newResult().error(new CustomError(msg, handlerParameters.getSourceLocation())).build()
64+
)
6365
}
6466
}
6567

@@ -99,7 +101,7 @@ class DataFetcherExceptionHandlerTest extends Specification {
99101
def "if an exception handler itself throws an exception than that is handled"() {
100102
DataFetcherExceptionHandler handler = new DataFetcherExceptionHandler() {
101103
@Override
102-
DataFetcherExceptionHandlerResult onException(DataFetcherExceptionHandlerParameters handlerParameters) {
104+
CompletableFuture<DataFetcherExceptionHandlerResult> handleException(DataFetcherExceptionHandlerParameters handlerParameters) {
103105
throw new RuntimeException("The handler itself went BANG!")
104106
}
105107
}

src/test/groovy/graphql/execution/ExecutionStrategyTest.groovy

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -575,16 +575,18 @@ class ExecutionStrategyTest extends Specification {
575575

576576
boolean handlerCalled = false
577577
ExecutionStrategy overridingStrategy = new AsyncExecutionStrategy(new SimpleDataFetcherExceptionHandler() {
578+
579+
578580
@Override
579-
DataFetcherExceptionHandlerResult onException(DataFetcherExceptionHandlerParameters handlerParameters) {
581+
CompletableFuture<DataFetcherExceptionHandlerResult> handleException(DataFetcherExceptionHandlerParameters handlerParameters) {
580582
handlerCalled = true
581583
assert handlerParameters.exception == expectedException
582584
assert handlerParameters.fieldDefinition == fieldDefinition
583585
assert handlerParameters.field.name == 'someField'
584586
assert handlerParameters.path == expectedPath
585587

586588
// by calling down we are testing the base class as well
587-
super.onException(handlerParameters)
589+
super.handleException(handlerParameters)
588590
}
589591
}) {
590592
@Override

src/test/groovy/graphql/execution/SimpleDataFetcherExceptionHandlerTest.groovy

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,26 @@ class SimpleDataFetcherExceptionHandlerTest extends Specification {
4646
! result.errors[0].getMessage().contains("BANG")
4747
}
4848

49+
static class MyHandler implements DataFetcherExceptionHandler {}
50+
51+
def "a class can work without implementing anything"() {
52+
when:
53+
DataFetcherExceptionHandler handler = new MyHandler()
54+
def handlerParameters = mkParams(new RuntimeException("RTE"))
55+
def result = handler.onException(handlerParameters)
56+
57+
then:
58+
result.errors[0] instanceof ExceptionWhileDataFetching
59+
result.errors[0].getMessage().contains("RTE")
60+
61+
when:
62+
def resultCF = handler.handleException(handlerParameters)
63+
64+
then:
65+
resultCF.join().errors[0] instanceof ExceptionWhileDataFetching
66+
resultCF.join().errors[0].getMessage().contains("RTE")
67+
}
68+
4969
private static DataFetcherExceptionHandlerParameters mkParams(Exception exception) {
5070
def mergedField = newMergedField(newField("f").build()).build()
5171
def esi = newExecutionStepInfo()

0 commit comments

Comments
 (0)