【问题标题】:GraphQL.ExecutionError: Error trying to resolveGraphQL.ExecutionError:尝试解决时出错
【发布时间】:2021-10-14 20:56:31
【问题描述】:

总结:

我的 GraphQL ExecuteAsync 返回包含的结果。根据下面提供的stackTrace,系统无法解析我的自定义类型remitsGeneralSearch。 remitsGeneralSearch 解析器可以返回一个名为 ClaimPaymentOrCheckSearchGraphType 的类型,它是一个 UnionGraphType。

堆栈跟踪: ["GraphQL.ExecutionError: 尝试解决 remitsGeneralSearch 时出错。\n ---> System.InvalidOperationException: Unexpected type: \n at GraphQL.Execution.ExecutionStrategy.BuildExecutionNode(ExecutionNode parent, IGraphType graphType, Field field, FieldType fieldDefinition, String[ ] path)\n 在 GraphQL.Execution.ExecutionStrategy.SetSubFieldNodes(ExecutionContext context, ObjectExecutionNode parent, Dictionary`2 fields)\n 在 GraphQL.Execution.ExecutionStrategy.SetSubFieldNodes(ExecutionContext context, ObjectExecutionNode parent)\n 在 GraphQL.Execution.ExecutionStrategy .ExecuteNodeAsync(ExecutionContext context, ExecutionNode node)\n --- 内部异常堆栈跟踪结束---"]4008305)

GraphQL 版本: 2.4.0

框架:.Net

操作系统: MacOS Catalina

引用的链接: https://github.com/graphql-dotnet/graphql-dotnet/issues/964

代码片段:

解析器:

    FieldAsync<ClaimPaymentOrCheckSearchGraphType>(
                "remitsGeneralSearch",
                resolve: async context =>
    {
        var securityFilter = await GetUserRemitFilters(context);
        var range = context.GetRange();
        var sortFields = context.GetArgument<List<SortField>>("sort") ?? Enumerable.Empty<SortField>();
        var whereClaimPayment = context.GetArgument<ClaimPaymentSearchFilter>("whereClaimPayment");
    
   Connection<ClaimPaymentSearchRow> claimPaymentSearchRowResult;
    
        try
        {
                using (LogContext.PushProperty("where", whereClaimPayment, true))
                                                {
              //claimPaymentSearchRowResult = await DMAQueryService.GetRemitReadersAsync(context);
            var whereArguments = context.Arguments["whereClaimPayment"] as Dictionary<string, object>;
            claimPaymentSearchRowResult = await DMAQueryService.GetRemitReadersAsync(
                                range,
                                whereClaimPayment,
                                whereArguments,
                                sortFields,
                                securityFilter,
                                context.CancellationToken
                );
            }
        }
        catch (Exception e)
        {
            _logger.LogInformation("Exception occurred {e}", e);
            throw e;
        }
    
        var userRemitFilters = context.UserContext as Services.DMA.UserRemitFilters;
    
    if (claimPaymentSearchRowResult.EdgeCount > 0)
    {
        return claimPaymentSearchRowResult;
    }
    
    var _whereCheckSearch = context.GetArgument<CheckSearchFilter>("whereCheck");
    
    try
    {
        Connection<CheckSearchRow> checkSearchRowResult;
        using (LogContext.PushProperty("whereCheck", _whereCheckSearch, true))
        {
          checkSearchRowResult = await DMAQueryService.GetCheckReadersAsync(context);
          return checkSearchRowResult;
        }
    }
    catch (Exception e)
    {
       throw e;
    }
  },arguments: queryArguments
 );
}
catch (Exception e)
{
   throw e;
}

自定义图形类型:

[Transient]
    public class ClaimPaymentOrCheckSearchGraphType : UnionGraphType
    {
        private readonly ILogger<ClaimPaymentOrCheckSearchGraphType> _logger;
        public ClaimPaymentOrCheckSearchGraphType(
            ILogger<ClaimPaymentOrCheckSearchGraphType> logger,
            ConnectionGraphType<ClaimPaymentSearchGraphType> claimPaymentSearchGraphType,
            ConnectionGraphType<CheckSearchGraphType> checkSearchGraphType
        )
        {
            _logger = logger;
            Type<ConnectionGraphType<ClaimPaymentSearchGraphType>>();
            Type<ConnectionGraphType<CheckSearchGraphType>>();

            ResolveType = obj =>
            {
                try
                {
                    if (obj is Connection<ClaimPaymentSearchRow>)
                    {
                        return claimPaymentSearchGraphType;
                    }

                    if (obj is Connection<CheckSearchRow>)
                    {
                        return checkSearchGraphType;
                    }

                    throw new ArgumentOutOfRangeException($"Could not resolve graph type for {obj.GetType().Name}");
                }
                catch (Exception e)
                {
                    _logger.LogInformation("ClaimPaymentOrCheckSearchGraphType Exception {e}: ", e);
                    throw e;
                }

            };
        }
    }

【问题讨论】:

    标签: graphql


    【解决方案1】:

    在此处找到答案的链接:https://github.com/graphql-dotnet/graphql-dotnet/issues/2674Try 替换此:

    Type<ConnectionGraphType<ClaimPaymentSearchGraphType>>();
    Type<ConnectionGraphType<CheckSearchGraphType>>();
    

    用这个:

    AddPossibleType(claimPaymentSearchGraphType);
    AddPossibleType(checkSearchGraphType);
    

    我在想,如果您将这些类型注册为瞬态,那么注册到架构初始化代码的副本是从 ResolveType 返回的不同副本。因此,从未设置其字段的 ResolvedType 属性,因此将 null 传递给 BuildExecutionNode 的 graphType 而不是已解析的类型。

    如果 ResolveType 方法可以返回一个类型而不是一个实例,那么就不会有问题,但不幸的是它不是这样工作的。或者您可以将类型注册为单例。

    【讨论】:

      猜你喜欢
      • 2019-12-07
      • 2016-12-03
      • 2017-09-12
      • 1970-01-01
      • 2017-11-06
      • 2015-10-09
      • 1970-01-01
      • 2014-01-27
      • 1970-01-01
      相关资源
      最近更新 更多