@@ -15,6 +15,7 @@ namespace HotChocolate;
15
15
internal sealed class SemanticNonNullTypeInterceptor : TypeInterceptor
16
16
{
17
17
private ITypeInspector _typeInspector = null ! ;
18
+ private ObjectTypeDefinition ? _mutationDef ;
18
19
19
20
public override bool IsEnabled ( IDescriptorContext context )
20
21
=> context . Options . EnableSemanticNonNull ;
@@ -29,52 +30,16 @@ internal override void InitializeContext(
29
30
_typeInspector = context . TypeInspector ;
30
31
}
31
32
32
- /// <summary>
33
- /// After the root types have been resolved, we go through all the fields of the mutation type
34
- /// and undo semantic non-nullability. This is because mutations can be chained and we want to retain
35
- /// the null-bubbling so execution is aborted once one non-null mutation field produces an error.
36
- /// We have to do this in a different hook because the mutation type is not yet fully resolved in the
37
- /// <see cref="OnAfterCompleteName"/> hook.
38
- /// </summary>
39
- public override void OnAfterResolveRootType (
40
- ITypeCompletionContext completionContext ,
41
- ObjectTypeDefinition definition ,
33
+ public override void OnAfterResolveRootType ( ITypeCompletionContext completionContext , ObjectTypeDefinition definition ,
42
34
OperationType operationType )
43
35
{
44
- if ( operationType == OperationType . Mutation )
36
+ if ( operationType is OperationType . Mutation )
45
37
{
46
- foreach ( var field in definition . Fields )
47
- {
48
- if ( field . IsIntrospectionField )
49
- {
50
- continue ;
51
- }
52
-
53
- if ( ! field . HasDirectives )
54
- {
55
- continue ;
56
- }
57
-
58
- var semanticNonNullDirective =
59
- field . Directives . FirstOrDefault ( d => d . Value is SemanticNonNullDirective ) ;
60
-
61
- if ( semanticNonNullDirective is not null )
62
- {
63
- field . Directives . Remove ( semanticNonNullDirective ) ;
64
- }
65
-
66
- var semanticNonNullFormatterDefinition =
67
- field . FormatterDefinitions . FirstOrDefault ( fd => fd . Key == WellKnownMiddleware . SemanticNonNull ) ;
68
-
69
- if ( semanticNonNullFormatterDefinition is not null )
70
- {
71
- field . FormatterDefinitions . Remove ( semanticNonNullFormatterDefinition ) ;
72
- }
73
- }
38
+ _mutationDef = definition ;
74
39
}
75
40
}
76
41
77
- public override void OnAfterCompleteName ( ITypeCompletionContext completionContext , DefinitionBase definition )
42
+ public override void OnBeforeCompleteType ( ITypeCompletionContext completionContext , DefinitionBase definition )
78
43
{
79
44
if ( completionContext . IsIntrospectionType )
80
45
{
@@ -88,6 +53,14 @@ public override void OnAfterCompleteName(ITypeCompletionContext completionContex
88
53
return ;
89
54
}
90
55
56
+ // We undo semantic non-nullability on each mutation field, since mutations can be chained
57
+ // and we want to retain the null-bubbling so execution is aborted if a non-null mutation field
58
+ // produces an error.
59
+ if ( objectDef == _mutationDef )
60
+ {
61
+ return ;
62
+ }
63
+
91
64
foreach ( var field in objectDef . Fields )
92
65
{
93
66
if ( field . IsIntrospectionField )
0 commit comments