15
15
use GraphQL \Type \Definition \Type ;
16
16
use GraphQL \Type \Definition \WrappingType ;
17
17
use GraphQL \Type \Introspection ;
18
+ use GraphQL \Type \Schema ;
18
19
use XGraphQL \DelegateExecution \Exception \LogicException ;
19
20
use XGraphQL \Utils \SelectionSet ;
20
21
@@ -35,33 +36,57 @@ public function __construct(
35
36
public function __invoke (mixed $ value , array $ arguments , mixed $ context , ResolveInfo $ info ): Promise
36
37
{
37
38
if (!isset ($ this ->delegatedPromises [$ info ->operation ])) {
39
+ $ this ->delegatedPromises [$ info ->operation ] = $ this ->delegateToExecute (
40
+ $ info ->schema ,
41
+ $ info ->operation ,
42
+ $ info ->fragments ,
43
+ $ info ->variableValues
44
+ );
45
+ }
46
+
47
+ return $ this ->resolve ($ info );
48
+ }
49
+
50
+
51
+ /**
52
+ * @param Schema $schema
53
+ * @param OperationDefinitionNode $operation
54
+ * @param array<string, FragmentDefinitionNode> $fragments
55
+ * @param array<string, mixed> $variables
56
+ * @return Promise
57
+ */
58
+ private function delegateToExecute (Schema $ schema , OperationDefinitionNode $ operation , array $ fragments , array $ variables ): Promise
59
+ {
60
+ try {
38
61
/// We need to clone all fragments and operation to make sure it can not be mutated by delegator.
39
- $ operation = $ info -> operation ->cloneDeep ();
40
- $ fragments = array_map (fn (FragmentDefinitionNode $ fragment ) => $ fragment ->cloneDeep (), $ info -> fragments );
62
+ $ delegateOperation = $ operation ->cloneDeep ();
63
+ $ delegateFragments = array_map (fn (FragmentDefinitionNode $ fragment ) => $ fragment ->cloneDeep (), $ fragments );
41
64
42
65
/// Add typename for detecting object type of interface or union
43
- SelectionSet::addTypename ($ operation ->getSelectionSet ());
44
- SelectionSet::addTypenameToFragments ($ fragments );
45
-
46
- $ this ->delegatedPromises [$ info ->operation ] = $ this
47
- ->delegator
48
- ->delegate (
49
- $ info ->schema ,
50
- $ operation ,
51
- $ fragments ,
52
- $ info ->variableValues
53
- )->then (
54
- function (ExecutionResult $ result ): ExecutionResult {
55
- if ([] !== $ result ->errors ) {
56
- $ this ->delegatedErrorsReporter ?->reportErrors($ result ->errors );
57
- }
58
-
59
- return $ result ;
60
- }
61
- );
66
+ SelectionSet::addTypename ($ delegateOperation ->getSelectionSet ());
67
+ SelectionSet::addTypenameToFragments ($ delegateFragments );
68
+
69
+ $ promise = $ this ->delegator ->delegate ($ schema , $ delegateOperation , $ delegateFragments , $ variables );
70
+ } catch (\Throwable $ exception ) {
71
+ $ result = new ExecutionResult (
72
+ null ,
73
+ [
74
+ new Error ('Error during delegate execution ' , [$ operation ], previous: $ exception )
75
+ ],
76
+ );
77
+
78
+ $ promise = $ this ->delegator ->getPromiseAdapter ()->createFulfilled ($ result );
62
79
}
63
80
64
- return $ this ->resolve ($ info );
81
+ return $ promise ->then (
82
+ function (ExecutionResult $ result ): ExecutionResult {
83
+ if ([] !== $ result ->errors ) {
84
+ $ this ->delegatedErrorsReporter ?->reportErrors($ result ->errors );
85
+ }
86
+
87
+ return $ result ;
88
+ }
89
+ );
65
90
}
66
91
67
92
private function resolve (ResolveInfo $ info ): Promise
@@ -72,7 +97,7 @@ private function resolve(ResolveInfo $info): Promise
72
97
73
98
$ promise = $ this ->delegatedPromises [$ info ->operation ];
74
99
75
- return $ promise ->then (fn (ExecutionResult $ result ) => $ this ->accessResultByPath ($ info ->path , $ result ));
100
+ return $ promise ->then (fn (ExecutionResult $ result ) => $ this ->accessResultByPath ($ info ->path , $ result ));
76
101
}
77
102
78
103
private function prepareTypeResolver (Type $ type ): void
0 commit comments