private async ValueTask <bool> TryExecuteAsync(CancellationToken cancellationToken) { try { // We will pre-check if the request was already canceled and mark the task as faulted if // this is the case. This essentially gives us a cheap and easy way out without any // exceptions. if (cancellationToken.IsCancellationRequested) { _completionStatus = ExecutionTaskStatus.Faulted; return(false); } // If the arguments are already parsed and processed we can just process. // Arguments need no pre-processing if they have no variables. if (Selection.Arguments.IsFinalNoErrors) { _resolverContext.Arguments = Selection.Arguments; await ExecuteResolverPipelineAsync(cancellationToken).ConfigureAwait(false); return(true); } // if this field has arguments that contain variables we first need to coerce them // before we can start executing the resolver. if (Selection.Arguments.TryCoerceArguments( _resolverContext, out IReadOnlyDictionary <NameString, ArgumentValue>?coercedArgs)) { _resolverContext.Arguments = coercedArgs; await ExecuteResolverPipelineAsync(cancellationToken).ConfigureAwait(false); return(true); } } catch (Exception ex) { if (!cancellationToken.IsCancellationRequested) { // If cancellation has not been requested for the request we assume this to // be a GraphQL resolver error and report it as such. // This will let the error handler produce a GraphQL error and // we set the result to null. ResolverContext.ReportError(ex); ResolverContext.Result = null; } } return(false); }
private async ValueTask <bool> TryExecuteAsync(CancellationToken cancellationToken) { try { if (cancellationToken.IsCancellationRequested) { return(false); } if (Selection.Arguments.IsFinalNoErrors) { ResolverContext.Arguments = Selection.Arguments; await ExecuteResolverPipelineAsync(cancellationToken).ConfigureAwait(false); return(true); } if (Selection.Arguments.TryCoerceArguments( ResolverContext, out IReadOnlyDictionary <NameString, ArgumentValue>?coercedArgs)) { ResolverContext.Arguments = coercedArgs; await ExecuteResolverPipelineAsync(cancellationToken).ConfigureAwait(false); return(true); } } catch (Exception ex) { if (!cancellationToken.IsCancellationRequested) { ResolverContext.ReportError(ex); ResolverContext.Result = null; } } return(false); }
private async ValueTask ExecuteResolverPipelineAsync(CancellationToken cancellationToken) { await ResolverContext.ResolverPipeline !(ResolverContext).ConfigureAwait(false); if (ResolverContext.Result is null) { return; } if (ResolverContext.Result is IError error) { ResolverContext.ReportError(error); ResolverContext.Result = null; return; } // if we are not a list we do not need any further result processing. if (!Selection.IsList) { return; } if (Selection.IsStreamable) { StreamDirective streamDirective = Selection.SyntaxNode.Directives.GetStreamDirective( ResolverContext.Variables) !; if (streamDirective.If) { ResolverContext.Result = await CreateStreamResultAsync(streamDirective) .ConfigureAwait(false); return; } } if (Selection.MaybeStream) { ResolverContext.Result = await CreateListFromStreamAsync() .ConfigureAwait(false); return; } switch (ResolverContext.Result) { case IExecutable executable: ResolverContext.Result = await executable .ToListAsync(cancellationToken) .ConfigureAwait(false); break; case IQueryable queryable: ResolverContext.Result = await Task.Run(() => { var items = new List <object?>(); foreach (var o in queryable) { items.Add(o); if (cancellationToken.IsCancellationRequested) { break; } } return(items); }, cancellationToken); break; } }