@@ -60,10 +60,12 @@ public abstract class InvocableHandlerMethodSupport extends HandlerMethod {
6060 */
6161protected InvocableHandlerMethodSupport (HandlerMethod handlerMethod , @ Nullable Executor executor ) {
6262super (handlerMethod .createWithResolvedBean ());
63+
6364this .hasCallableReturnValue = getReturnType ().getParameterType ().equals (Callable .class );
6465this .executor = executor ;
65- Assert .isTrue (!this .hasCallableReturnValue || this .executor != null ,
66- "Controller method declared with Callable return value, but no Executor configured: " +
66+
67+ Assert .isTrue (!this .hasCallableReturnValue || executor != null ,
68+ "Controller method has Callable return value, but Executor not provided: " +
6769handlerMethod .getBridgedMethod ().toGenericString ());
6870}
6971
@@ -86,8 +88,14 @@ protected Object doInvoke(GraphQLContext graphQLContext, Object... argValues) {
8688if (KotlinDetector .isSuspendingFunction (method )) {
8789return invokeSuspendingFunction (getBean (), method , argValues );
8890}
91+
8992Object result = method .invoke (getBean (), argValues );
90- return handleReturnValue (graphQLContext , result );
93+
94+ if (this .hasCallableReturnValue && result != null ) {
95+ result = adaptCallable (graphQLContext , (Callable <?>) result );
96+ }
97+
98+ return result ;
9199}
92100catch (IllegalArgumentException ex ) {
93101assertTargetBean (method , getBean (), argValues );
@@ -114,7 +122,7 @@ protected Object doInvoke(GraphQLContext graphQLContext, Object... argValues) {
114122private static Object invokeSuspendingFunction (Object bean , Method method , Object [] argValues ) {
115123Object result = CoroutinesUtils .invokeSuspendingFunction (method , bean , argValues );
116124
117- // Support DataLoader use
125+ // Support use of DataLoader from suspending function
118126Class <?> returnType = KotlinReflectionUtils .getReturnType (method );
119127if (CompletableFuture .class .isAssignableFrom (returnType )) {
120128return ((Mono <CompletableFuture <?>>) result ).flatMap (Mono ::fromFuture );
@@ -123,22 +131,16 @@ private static Object invokeSuspendingFunction(Object bean, Method method, Objec
123131return result ;
124132}
125133
126- @ Nullable
127- private Object handleReturnValue (GraphQLContext graphQLContext , @ Nullable Object result ) {
128- if (this .hasCallableReturnValue && result != null ) {
129- return CompletableFuture .supplyAsync (
130- () -> {
131- try {
132- return ContextSnapshotFactoryHelper .captureFrom (graphQLContext ).wrap ((Callable <?>) result ).call ();
133- }
134- catch (Exception ex ) {
135- throw new IllegalStateException (
136- "Failure in Callable returned from " + getBridgedMethod ().toGenericString (), ex );
137- }
138- },
139- this .executor );
140- }
141- return result ;
134+ private CompletableFuture <?> adaptCallable (GraphQLContext graphQLContext , Callable <?> result ) {
135+ return CompletableFuture .supplyAsync (() -> {
136+ try {
137+ return ContextSnapshotFactoryHelper .captureFrom (graphQLContext ).wrap (result ).call ();
138+ }
139+ catch (Exception ex ) {
140+ String msg = "Failure in Callable returned from " + getBridgedMethod ().toGenericString ();
141+ throw new IllegalStateException (msg , ex );
142+ }
143+ }, this .executor );
142144}
143145
144146/**
0 commit comments