diff --git a/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt b/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt index efd60cf7..c76023d5 100644 --- a/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt +++ b/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt @@ -15,6 +15,7 @@ import graphql.schema.DataFetchingEnvironment import graphql.schema.GraphQLTypeUtil.isScalar import kotlinx.coroutines.future.future import org.slf4j.LoggerFactory +import java.lang.reflect.InvocationTargetException import java.lang.reflect.Method import java.util.* import kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn @@ -251,20 +252,11 @@ private suspend inline fun invokeSuspend(target: Any, resolverMethod: Method, ar } } -@Suppress("NOTHING_TO_INLINE") -private inline fun invoke(method: Method, instance: Any, args: Array): Any? { +private fun invoke(method: Method, instance: Any, args: Array): Any? { try { return method.invoke(instance, *args) - } catch (invocationException: java.lang.reflect.InvocationTargetException) { - val e = invocationException.cause - if (e is RuntimeException) { - throw e - } - if (e is Error) { - throw e - } - - throw java.lang.reflect.UndeclaredThrowableException(e) + } catch (e: InvocationTargetException) { + throw e.cause ?: RuntimeException("Unknown error occurred while invoking resolver method") } } diff --git a/src/test/kotlin/graphql/kickstart/tools/MethodFieldResolverTest.kt b/src/test/kotlin/graphql/kickstart/tools/MethodFieldResolverTest.kt index 1c647da0..642fe6c5 100644 --- a/src/test/kotlin/graphql/kickstart/tools/MethodFieldResolverTest.kt +++ b/src/test/kotlin/graphql/kickstart/tools/MethodFieldResolverTest.kt @@ -1,5 +1,6 @@ package graphql.kickstart.tools +import graphql.ExceptionWhileDataFetching import graphql.ExecutionInput import graphql.GraphQL import graphql.GraphQLContext @@ -210,6 +211,34 @@ class MethodFieldResolverTest { assertEquals(result.getData(), mapOf("test" to 6)) } + @Test + fun `should unwrap and rethrow resolver exceptions`() { + val schema = SchemaParser.newParser() + .schemaString( + """ + type Query { + test: String + } + """) + .resolvers(object : GraphQLQueryResolver { + fun test(): String = throw Exception("Whoops") + }) + .build() + .makeExecutableSchema() + + val gql = GraphQL.newGraphQL(schema).build() + val result = gql.execute(ExecutionInput.newExecutionInput().query( + """ + query { + test + } + """)) + + assertEquals(result.errors.size, 1) + val exceptionWhileDataFetching = result.errors[0] as ExceptionWhileDataFetching + assertEquals(exceptionWhileDataFetching.exception.message, "Whoops") + } + /** * Custom Scalar Class type that doesn't work with Jackson serialization/deserialization */