diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/CachingGraphQLService.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/CachingGraphQLService.cs index ce4af1bdd..09ddaafdc 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/CachingGraphQLService.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/CachingGraphQLService.cs @@ -15,6 +15,7 @@ using Squidex.Domain.Apps.Core; using Squidex.Domain.Apps.Entities.Apps; using Squidex.Domain.Apps.Entities.Assets; using Squidex.Infrastructure; +using Squidex.Infrastructure.Log; namespace Squidex.Domain.Apps.Entities.Contents.GraphQL { @@ -94,7 +95,8 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL allSchemas, GetPageSizeForContents(), GetPageSizeForAssets(), - resolver.GetRequiredService()); + resolver.GetRequiredService(), + resolver.GetRequiredService()); }); } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLModel.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLModel.cs index e62f2b17e..8de5298db 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLModel.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLModel.cs @@ -17,6 +17,7 @@ using Squidex.Domain.Apps.Entities.Contents.GraphQL.Types; using Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Utils; using Squidex.Domain.Apps.Entities.Schemas; using Squidex.Infrastructure; +using Squidex.Infrastructure.Log; using GraphQLSchema = GraphQL.Types.Schema; #pragma warning disable IDE0003 @@ -31,6 +32,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL private readonly IObjectGraphType assetType; private readonly IGraphType assetListType; private readonly GraphQLSchema graphQLSchema; + private readonly ISemanticLog log; public bool CanGenerateAssetSourceUrl { get; } @@ -43,8 +45,10 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL IEnumerable schemas, int pageSizeContents, int pageSizeAssets, - IUrlGenerator urlGenerator) + IUrlGenerator urlGenerator, ISemanticLog log) { + this.log = log; + partitionResolver = app.PartitionResolver(); CanGenerateAssetSourceUrl = urlGenerator.CanGenerateAssetSourceUrl; @@ -147,7 +151,21 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL execution.Schema = graphQLSchema; execution.Inputs = query.Inputs; execution.Query = query.Query; - }).ConfigureAwait(false); + }); + + if (result.Errors != null && result.Errors.Any()) + { + log.LogWarning(w => w + .WriteProperty("action", "GraphQL") + .WriteProperty("status", "Failed") + .WriteArray("errors", a => + { + foreach (var error in result.Errors) + { + a.WriteObject(error, (error, e) => e.WriteException(error)); + } + })); + } var errors = result.Errors?.Select(x => (object)new { x.Message, x.Locations }).ToArray(); diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ContentGraphType.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ContentGraphType.cs index c8e857fac..a6dbe63a3 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ContentGraphType.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ContentGraphType.cs @@ -5,6 +5,7 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using System; using System.Collections.Generic; using System.Linq; using GraphQL.Types; @@ -20,12 +21,12 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types public ContentGraphType(ISchemaEntity schema) { - this.schemaId = schema.Id; + schemaId = schema.Id; var schemaType = schema.TypeName(); var schemaName = schema.DisplayName(); - Name = $"{schemaType}"; + Name = schemaType.SafeTypeName(); AddField(new FieldType { diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Extensions.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Extensions.cs index 78bf139cc..797bea745 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Extensions.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Extensions.cs @@ -5,6 +5,7 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using System; using System.Collections.Generic; using System.Linq; using GraphQL; @@ -17,6 +18,16 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types { public static class Extensions { + public static string SafeTypeName(this string typeName) + { + if (typeName.Equals("Content", StringComparison.Ordinal)) + { + return $"{typeName}Entity"; + } + + return typeName; + } + public static IEnumerable<(T Field, string Name, string Type)> SafeFields(this IEnumerable fields) where T : IField { var allFields = diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLTestBase.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLTestBase.cs index b4aaf4c8b..2cac0ce2c 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLTestBase.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLTestBase.cs @@ -41,11 +41,13 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL protected readonly ISchemaEntity schema; protected readonly ISchemaEntity schemaRef1; protected readonly ISchemaEntity schemaRef2; + protected readonly ISchemaEntity schemaInvalidName; protected readonly Context requestContext; protected readonly NamedId appId = NamedId.Of(DomainId.NewGuid(), "my-app"); protected readonly NamedId schemaId = NamedId.Of(DomainId.NewGuid(), "my-schema"); protected readonly NamedId schemaRefId1 = NamedId.Of(DomainId.NewGuid(), "my-ref-schema1"); protected readonly NamedId schemaRefId2 = NamedId.Of(DomainId.NewGuid(), "my-ref-schema2"); + protected readonly NamedId schemaInvalidNameId = NamedId.Of(DomainId.NewGuid(), "content"); protected readonly IGraphQLService sut; public GraphQLTestBase() @@ -107,6 +109,13 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL schemaRef2 = Mocks.Schema(appId, schemaRefId2, schemaRef2Def); + var schemaInvalidNameDef = + new Schema(schemaInvalidNameId.Name) + .Publish() + .AddString(1, "my-field", Partitioning.Invariant); + + schemaInvalidName = Mocks.Schema(appId, schemaInvalidNameId, schemaInvalidNameDef); + requestContext = new Context(Mocks.FrontendUser(), app); sut = CreateSut(); @@ -139,7 +148,13 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL var appProvider = A.Fake(); A.CallTo(() => appProvider.GetSchemasAsync(testBase.appId.Id)) - .Returns(new List { testBase.schema, testBase.schemaRef1, testBase.schemaRef2 }); + .Returns(new List + { + testBase.schema, + testBase.schemaRef1, + testBase.schemaRef2, + testBase.schemaInvalidName + }); var dataLoaderContext = new DataLoaderContextAccessor();