Skip to content

Commit e5d8302

Browse files
tobias-tenglermichaelstaib
authored andcommitted
Fix @semanticNonNull on mutation types (#8239)
1 parent c808703 commit e5d8302

File tree

3 files changed

+22
-41
lines changed

3 files changed

+22
-41
lines changed

src/HotChocolate/Core/src/Types/SemanticNonNullTypeInterceptor.cs

Lines changed: 13 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ namespace HotChocolate;
1515
internal sealed class SemanticNonNullTypeInterceptor : TypeInterceptor
1616
{
1717
private ITypeInspector _typeInspector = null!;
18+
private ObjectTypeDefinition? _mutationDef;
1819

1920
public override bool IsEnabled(IDescriptorContext context)
2021
=> context.Options.EnableSemanticNonNull;
@@ -29,52 +30,16 @@ internal override void InitializeContext(
2930
_typeInspector = context.TypeInspector;
3031
}
3132

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,
4234
OperationType operationType)
4335
{
44-
if (operationType == OperationType.Mutation)
36+
if (operationType is OperationType.Mutation)
4537
{
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;
7439
}
7540
}
7641

77-
public override void OnAfterCompleteName(ITypeCompletionContext completionContext, DefinitionBase definition)
42+
public override void OnBeforeCompleteType(ITypeCompletionContext completionContext, DefinitionBase definition)
7843
{
7944
if (completionContext.IsIntrospectionType)
8045
{
@@ -88,6 +53,14 @@ public override void OnAfterCompleteName(ITypeCompletionContext completionContex
8853
return;
8954
}
9055

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+
9164
foreach (var field in objectDef.Fields)
9265
{
9366
if (field.IsIntrospectionField)

src/HotChocolate/Core/test/Types.Tests/SemanticNonNullTests.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ public async Task MutationConventions()
3535
o.StrictValidation = false;
3636
o.EnableSemanticNonNull = true;
3737
})
38-
.AddMutationConventions()
38+
.AddMutationConventions(applyToAllMutations: false)
3939
.AddMutationType<Mutation>()
40+
.AddTypeExtension<MutationExtensions>()
4041
.BuildSchemaAsync()
4142
.MatchSnapshotAsync();
4243
}
@@ -319,6 +320,12 @@ public class Mutation
319320
public bool DoSomething() => true;
320321
}
321322

323+
[ExtendObjectType<Mutation>]
324+
public class MutationExtensions
325+
{
326+
public bool DoSomethingElse() => true;
327+
}
328+
322329
public class MyException : Exception;
323330

324331
public class QueryWithPagination

src/HotChocolate/Core/test/Types.Tests/__snapshots__/SemanticNonNullTests.MutationConventions.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ type DoSomethingPayload {
1313

1414
type Mutation {
1515
doSomething: DoSomethingPayload!
16+
doSomethingElse: Boolean!
1617
}
1718

1819
type MyError implements Error {

0 commit comments

Comments
 (0)