Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,6 @@
<artifactId>jackson-datatype-jdk8</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>reflectasm</artifactId>
<version>1.11.9</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
Expand Down
30 changes: 22 additions & 8 deletions src/main/kotlin/graphql/kickstart/tools/MethodFieldResolver.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package graphql.kickstart.tools

import com.esotericsoftware.reflectasm.MethodAccess
import com.fasterxml.jackson.core.type.TypeReference
import graphql.TrivialDataFetcher
import graphql.execution.batched.Batched
Expand Down Expand Up @@ -182,9 +181,7 @@ internal class MethodFieldResolver(field: FieldDefinition, search: FieldResolver

open class MethodFieldResolverDataFetcher(private val sourceResolver: SourceResolver, method: Method, private val args: List<ArgumentPlaceholder>, private val options: SchemaParserOptions) : DataFetcher<Any> {

// Convert to reflactasm reflection
private val methodAccess = MethodAccess.get(method.declaringClass)!!
private val methodIndex = methodAccess.getIndex(method.name, *method.parameterTypes)
private val resolverMethod = method
private val isSuspendFunction = try {
method.kotlinFunction?.isSuspend == true
} catch (e: InternalError) {
Expand All @@ -206,10 +203,10 @@ open class MethodFieldResolverDataFetcher(private val sourceResolver: SourceReso

return if (isSuspendFunction) {
environment.coroutineScope().future(options.coroutineContextProvider.provide()) {
methodAccess.invokeSuspend(source, methodIndex, args)?.transformWithGenericWrapper(environment)
invokeSuspend(source, resolverMethod, args)?.transformWithGenericWrapper(environment)
}
} else {
methodAccess.invoke(source, methodIndex, *args)?.transformWithGenericWrapper(environment)
invoke(resolverMethod, source, args)?.transformWithGenericWrapper(environment)
}
}

Expand All @@ -236,9 +233,26 @@ open class TrivialMethodFieldResolverDataFetcher(sourceResolver: SourceResolver,

}

private suspend inline fun MethodAccess.invokeSuspend(target: Any, methodIndex: Int, args: Array<Any?>): Any? {
private suspend inline fun invokeSuspend(target: Any, resolverMethod: Method, args: Array<Any?>): Any? {
return suspendCoroutineUninterceptedOrReturn { continuation ->
invoke(target, methodIndex, *args + continuation)
invoke(resolverMethod, target, args + continuation)
}
}

@Suppress("NOTHING_TO_INLINE")
private inline fun invoke(method: Method, instance:Any, args: Array<Any?>): 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);
}
}

Expand Down
14 changes: 14 additions & 0 deletions src/test/groovy/graphql/kickstart/tools/EndToEndSpec.groovy
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package graphql.kickstart.tools

import graphql.ExecutionInput
import graphql.ExecutionResult
import graphql.GraphQL
import graphql.execution.AsyncExecutionStrategy
Expand Down Expand Up @@ -664,4 +665,17 @@ class EndToEndSpec extends Specification {
data.arrayItems.collect { it.name } == ['item1', 'item2']
}

def "generated schema should re-throw original runtime exception when executing a resolver method"() {
when:

gql.execute(ExecutionInput.newExecutionInput().query('''
{
throwsIllegalArgumentException
}
'''
))

then:
IllegalArgumentException
}
}
6 changes: 6 additions & 0 deletions src/test/kotlin/graphql/kickstart/tools/EndToEndSpecHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ type Query {
coroutineItems: [Item!]!

arrayItems: [Item!]!

throwsIllegalArgumentException: String
}

type ExtendedType {
Expand Down Expand Up @@ -296,6 +298,10 @@ class Query : GraphQLQueryResolver, ListListResolver<String>() {
suspend fun coroutineItems(): List<Item> = CompletableDeferred(items).await()

fun arrayItems() = items.toTypedArray()

fun throwsIllegalArgumentException(): String {
throw IllegalArgumentException("Expected")
}
}

class UnusedRootResolver : GraphQLQueryResolver
Expand Down