@@ -60,10 +60,12 @@ public abstract class InvocableHandlerMethodSupport extends HandlerMethod {
60
60
*/
61
61
protected InvocableHandlerMethodSupport (HandlerMethod handlerMethod , @ Nullable Executor executor ) {
62
62
super (handlerMethod .createWithResolvedBean ());
63
+
63
64
this .hasCallableReturnValue = getReturnType ().getParameterType ().equals (Callable .class );
64
65
this .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: " +
67
69
handlerMethod .getBridgedMethod ().toGenericString ());
68
70
}
69
71
@@ -86,8 +88,14 @@ protected Object doInvoke(GraphQLContext graphQLContext, Object... argValues) {
86
88
if (KotlinDetector .isSuspendingFunction (method )) {
87
89
return invokeSuspendingFunction (getBean (), method , argValues );
88
90
}
91
+
89
92
Object 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 ;
91
99
}
92
100
catch (IllegalArgumentException ex ) {
93
101
assertTargetBean (method , getBean (), argValues );
@@ -114,7 +122,7 @@ protected Object doInvoke(GraphQLContext graphQLContext, Object... argValues) {
114
122
private static Object invokeSuspendingFunction (Object bean , Method method , Object [] argValues ) {
115
123
Object result = CoroutinesUtils .invokeSuspendingFunction (method , bean , argValues );
116
124
117
- // Support DataLoader use
125
+ // Support use of DataLoader from suspending function
118
126
Class <?> returnType = KotlinReflectionUtils .getReturnType (method );
119
127
if (CompletableFuture .class .isAssignableFrom (returnType )) {
120
128
return ((Mono <CompletableFuture <?>>) result ).flatMap (Mono ::fromFuture );
@@ -123,22 +131,16 @@ private static Object invokeSuspendingFunction(Object bean, Method method, Objec
123
131
return result ;
124
132
}
125
133
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 );
142
144
}
143
145
144
146
/**
0 commit comments