상속: System.Exception
예제 #1
0
 public static async Task <TResult> TryAsyncResolve <TResult>(this IResolveFieldContext context, Func <IResolveFieldContext, Task <TResult> > resolve, Func <ExecutionErrors, Task <TResult> > error = null)
 {
     try
     {
         return(await resolve(context).ConfigureAwait(false));
     }
     catch (Exception ex)
     {
         if (error == null)
         {
             var er = new ExecutionError(ex.Message, ex);
             er.AddLocation(context.FieldAst, context.Document);
             er.Path = context.Path;
             context.Errors.Add(er);
             return(default);
예제 #2
0
 public static void AddLocation(this ExecutionError error, AbstractNode abstractNode, Document document)
 {
     if (abstractNode != null)
     {
         if (document != null)
         {
             var location = new Location(new Source(document.OriginalQuery), abstractNode.SourceLocation.Start);
             error.AddLocation(location.Line, location.Column);
         }
         else if (abstractNode.SourceLocation.Line > 0 && abstractNode.SourceLocation.Column > 0)
         {
             error.AddLocation(abstractNode.SourceLocation.Line, abstractNode.SourceLocation.Column);
         }
     }
 }
예제 #3
0
        private ResolveFieldResult <object> GenerateError(
            ResolveFieldResult <object> resolveResult,
            Field field,
            ExecutionContext context,
            Exception exc,
            IEnumerable <string> path)
        {
            var error = new ExecutionError("Error trying to resolve {0}.".ToFormat(field.Name), exc);

            error.AddLocation(field, context.Document);
            error.Path = path;
            context.Errors.Add(error);
            resolveResult.Skip = false;
            return(resolveResult);
        }
        /// <summary>
        ///     Resolve lists in a performant manor
        /// </summary>
        private async Task <List <object> > ResolveListFromData(ExecutionContext context, object source, IObjectGraphType parentType,
                                                                IGraphType graphType, Field field, IEnumerable <string> path)
        {
            var result           = new List <object>();
            var listInfo         = graphType as ListGraphType;
            var subType          = listInfo?.ResolvedType as IObjectGraphType;
            var data             = source as IEnumerable;
            var visitedFragments = new List <string>();
            var subFields        = CollectFields(context, subType, field.SelectionSet, null, visitedFragments);

            if (data == null)
            {
                var error = new ExecutionError("User error: expected an IEnumerable list though did not find one.");
                error.AddLocation(field, context.Document);
                throw error;
            }

            var index = 0;

            foreach (var node in data)
            {
                var currentPath = path.Concat(new[] { $"{index++}" });

                if (subType != null)
                {
                    var nodeResult = await ExecuteFieldsAsync(context, subType, node, subFields, currentPath)
                                     .ConfigureAwait(false);

                    result.Add(nodeResult);
                }
                else
                {
                    var nodeResult = await CompleteValueAsync(context, parentType, listInfo?.ResolvedType, field, node, currentPath)
                                     .ConfigureAwait(false);

                    result.Add(nodeResult);
                }
            }

            return(result);
        }
        /// <summary>
        ///     Resolve simple fields in a performant manor
        /// </summary>
        private static async Task <object> ResolveFieldFromDataAsync(ExecutionContext context, IObjectGraphType rootType, object source,
                                                                     FieldType fieldType, Field field, IEnumerable <string> path)
        {
            object result = null;

            try
            {
                if (fieldType.Resolver != null)
                {
                    var rfc = new ResolveFieldContext(context, field, fieldType, source, rootType, null, path);

                    result = fieldType.Resolver.Resolve(rfc);

                    result = await UnwrapResultAsync(result)
                             .ConfigureAwait(false);
                }
                else
                {
                    result = NameFieldResolver.Resolve(source, field.Name);
                }

                if (result != null)
                {
                    var scalarType = fieldType.ResolvedType as ScalarGraphType;

                    result = scalarType?.Serialize(result);
                }
            }
            catch (Exception exc)
            {
                var error = new ExecutionError($"Error trying to resolve {field.Name}.", exc);
                error.AddLocation(field, context.Document);
                error.Path = path.ToList();
                context.Errors.Add(error);

                // If there was an exception, the value of result cannot be trusted
                result = null;
            }

            return(result);
        }
예제 #6
0
        public IObjectGraphType GetOperationRootType(Document document, ISchema schema, Operation operation)
        {
            IObjectGraphType type;

            ExecutionError error;

            switch (operation.OperationType)
            {
            case OperationType.Query:
                type = schema.Query;
                break;

            case OperationType.Mutation:
                type = schema.Mutation;
                if (type == null)
                {
                    error = new ExecutionError("Schema is not configured for mutations");
                    error.AddLocation(operation, document);
                    throw error;
                }
                break;

            case OperationType.Subscription:
                type = schema.Subscription;
                if (type == null)
                {
                    error = new ExecutionError("Schema is not configured for subscriptions");
                    error.AddLocation(operation, document);
                    throw error;
                }
                break;

            default:
                error = new ExecutionError("Can only execute queries, mutations and subscriptions.");
                error.AddLocation(operation, document);
                throw error;
            }

            return(type);
        }
        private void WriteErrorExtensions(ExecutionError error, JsonWriter writer, JsonSerializer serializer)
        {
            if (string.IsNullOrWhiteSpace(error.Code) && (error.Data == null || error.Data.Count == 0))
            {
                return;
            }

            writer.WritePropertyName("extensions");
            writer.WriteStartObject();

            if (!string.IsNullOrWhiteSpace(error.Code))
            {
                writer.WritePropertyName("code");
                serializer.Serialize(writer, error.Code);
            }

            if (error.HasCodes)
            {
                writer.WritePropertyName("codes");
                writer.WriteStartArray();
                error.Codes.Apply(code => serializer.Serialize(writer, code));
                writer.WriteEndArray();
            }

            if (error.Data?.Count > 0)
            {
                writer.WritePropertyName("data");
                writer.WriteStartObject();
                error.DataAsDictionary.Apply(entry =>
                {
                    writer.WritePropertyName(entry.Key);
                    serializer.Serialize(writer, entry.Value);
                });
                writer.WriteEndObject();
            }

            writer.WriteEndObject();
        }
예제 #8
0
        public FieldType GetFieldDefinition(Document document, ISchema schema, IObjectGraphType parentType, Field field)
        {
            if (field.Name == SchemaIntrospection.SchemaMeta.Name && schema.Query == parentType)
            {
                return(SchemaIntrospection.SchemaMeta);
            }
            if (field.Name == SchemaIntrospection.TypeMeta.Name && schema.Query == parentType)
            {
                return(SchemaIntrospection.TypeMeta);
            }
            if (field.Name == SchemaIntrospection.TypeNameMeta.Name)
            {
                return(SchemaIntrospection.TypeNameMeta);
            }

            if (parentType == null)
            {
                var error = new ExecutionError($"Schema is not configured correctly to fetch {field.Name}.  Are you missing a root type?");
                error.AddLocation(field, document);
                throw error;
            }

            return(parentType.Fields.FirstOrDefault(f => f.Name == field.Name));
        }
예제 #9
0
 public override void Add(ExecutionError error) => throw new NotSupportedException();
예제 #10
0
        public async Task <object> CompleteValueAsync(ExecutionContext context, IObjectGraphType parentType, IGraphType fieldType, Field field, object result, IEnumerable <string> path)
        {
            var fieldName = field?.Name;

            var nonNullType = fieldType as NonNullGraphType;

            if (nonNullType != null)
            {
                var type      = nonNullType.ResolvedType;
                var completed = await CompleteValueAsync(context, parentType, type, field, result, path).ConfigureAwait(false);

                if (completed == null)
                {
                    var error = new ExecutionError("Cannot return null for non-null type. Field: {0}, Type: {1}!."
                                                   .ToFormat(fieldName, type.Name));
                    error.AddLocation(field, context.Document);
                    throw error;
                }

                return(completed);
            }

            if (result == null)
            {
                return(null);
            }

            if (fieldType is ScalarGraphType)
            {
                var scalarType   = fieldType as ScalarGraphType;
                var coercedValue = scalarType.Serialize(result);
                return(coercedValue);
            }

            if (fieldType is ListGraphType)
            {
                var list = result as IEnumerable;

                if (list == null)
                {
                    var error = new ExecutionError("User error: expected an IEnumerable list though did not find one.");
                    error.AddLocation(field, context.Document);
                    throw error;
                }

                var listType = fieldType as ListGraphType;
                var itemType = listType.ResolvedType;

                var results = await list
                              .MapAsync(async (index, item) =>
                                        await CompleteValueAsync(context, parentType, itemType, field, item, path.Concat(new[] { $"{index}" })).ConfigureAwait(false))
                              .ConfigureAwait(false);

                return(results);
            }

            var objectType = fieldType as IObjectGraphType;

            if (fieldType is IAbstractGraphType)
            {
                var abstractType = fieldType as IAbstractGraphType;
                objectType = abstractType.GetObjectType(result);

                if (objectType == null)
                {
                    var error = new ExecutionError(
                        $"Abstract type {abstractType.Name} must resolve to an Object type at " +
                        $"runtime for field {parentType.Name}.{fieldName} " +
                        $"with value {result}, received 'null'.");
                    error.AddLocation(field, context.Document);
                    throw error;
                }

                if (!abstractType.IsPossibleType(objectType))
                {
                    var error = new ExecutionError(
                        "Runtime Object type \"{0}\" is not a possible type for \"{1}\""
                        .ToFormat(objectType, abstractType));
                    error.AddLocation(field, context.Document);
                    throw error;
                }
            }

            if (objectType == null)
            {
                return(null);
            }

            if (objectType.IsTypeOf != null && !objectType.IsTypeOf(result))
            {
                var error = new ExecutionError(
                    "Expected value of type \"{0}\" but got: {1}."
                    .ToFormat(objectType, result));
                error.AddLocation(field, context.Document);
                throw error;
            }

            var subFields        = new Dictionary <string, Field>();
            var visitedFragments = new List <string>();

            subFields = CollectFields(context, objectType, field?.SelectionSet, subFields, visitedFragments);

            return(await ExecuteFieldsAsync(context, objectType, result, subFields, path).ConfigureAwait(false));
        }
예제 #11
0
        public async Task <object> CompleteValueAsync(ExecutionContext context, IGraphType fieldType, Fields fields, object result)
        {
            var field = fields != null?fields.FirstOrDefault() : null;

            var fieldName = field != null ? field.Name : null;

            var nonNullType = fieldType as NonNullGraphType;

            if (nonNullType != null)
            {
                var type      = nonNullType.ResolvedType;
                var completed = await CompleteValueAsync(context, type, fields, result).ConfigureAwait(false);

                if (completed == null)
                {
                    var error = new ExecutionError("Cannot return null for non-null type. Field: {0}, Type: {1}!."
                                                   .ToFormat(fieldName, type.Name));
                    error.AddLocation(field, context.Document);
                    throw error;
                }

                return(completed);
            }

            if (result == null)
            {
                return(null);
            }

            if (fieldType is ScalarGraphType)
            {
                var scalarType   = fieldType as ScalarGraphType;
                var coercedValue = scalarType.Serialize(result);
                return(coercedValue);
            }

            if (fieldType is ListGraphType)
            {
                var list = result as IEnumerable;

                if (list == null)
                {
                    var error = new ExecutionError("User error: expected an IEnumerable list though did not find one.");
                    error.AddLocation(field, context.Document);
                    throw error;
                }

                var listType = fieldType as ListGraphType;
                var itemType = listType.ResolvedType;

                var results = await list.MapAsync(async item => await CompleteValueAsync(context, itemType, fields, item).ConfigureAwait(false)).ConfigureAwait(false);

                return(results);
            }

            var objectType = fieldType as IObjectGraphType;

            if (fieldType is IAbstractGraphType)
            {
                var abstractType = fieldType as IAbstractGraphType;
                objectType = abstractType.GetObjectType(result);

                if (objectType != null && !abstractType.IsPossibleType(objectType))
                {
                    var error = new ExecutionError(
                        "Runtime Object type \"{0}\" is not a possible type for \"{1}\""
                        .ToFormat(objectType, abstractType));
                    error.AddLocation(field, context.Document);
                    throw error;
                }
            }

            if (objectType == null)
            {
                return(null);
            }

            if (objectType.IsTypeOf != null && !objectType.IsTypeOf(result))
            {
                var error = new ExecutionError(
                    "Expected value of type \"{0}\" but got: {1}."
                    .ToFormat(objectType, result));
                error.AddLocation(field, context.Document);
                throw error;
            }

            var subFields        = new Dictionary <string, Fields>();
            var visitedFragments = new List <string>();

            fields.Apply(f =>
            {
                subFields = CollectFields(context, objectType, f.SelectionSet, subFields, visitedFragments);
            });

            return(await ExecuteFieldsAsync(context, objectType, result, subFields).ConfigureAwait(false));
        }
예제 #12
0
        public async Task <ResolveFieldResult <object> > ResolveFieldAsync(ExecutionContext context, IObjectGraphType parentType, object source, Fields fields)
        {
            context.CancellationToken.ThrowIfCancellationRequested();

            var resolveResult = new ResolveFieldResult <object>
            {
                Skip = false
            };

            var field = fields.First();

            var fieldDefinition = GetFieldDefinition(context.Schema, parentType, field);

            if (fieldDefinition == null)
            {
                resolveResult.Skip = true;
                return(resolveResult);
            }

            var arguments = GetArgumentValues(context.Schema, fieldDefinition.Arguments, field.Arguments, context.Variables);

            try
            {
                var resolveContext = new ResolveFieldContext();
                resolveContext.FieldName         = field.Name;
                resolveContext.FieldAst          = field;
                resolveContext.FieldDefinition   = fieldDefinition;
                resolveContext.ReturnType        = fieldDefinition.ResolvedType;
                resolveContext.ParentType        = parentType;
                resolveContext.Arguments         = arguments;
                resolveContext.Source            = source;
                resolveContext.Schema            = context.Schema;
                resolveContext.Document          = context.Document;
                resolveContext.Fragments         = context.Fragments;
                resolveContext.RootValue         = context.RootValue;
                resolveContext.UserContext       = context.UserContext;
                resolveContext.Operation         = context.Operation;
                resolveContext.Variables         = context.Variables;
                resolveContext.CancellationToken = context.CancellationToken;
                resolveContext.Metrics           = context.Metrics;

                var resolver = fieldDefinition.Resolver ?? new NameFieldResolver();
                var result   = resolver.Resolve(resolveContext);

                if (result is Task)
                {
                    var task = result as Task;
                    await task.ConfigureAwait(false);

                    result = task.GetProperyValue("Result");
                }

                resolveResult.Value =
                    await CompleteValueAsync(context, fieldDefinition.ResolvedType, fields, result).ConfigureAwait(false);

                return(resolveResult);
            }
            catch (Exception exc)
            {
                var error = new ExecutionError("Error trying to resolve {0}.".ToFormat(field.Name), exc);
                error.AddLocation(field, context.Document);
                context.Errors.Add(error);
                resolveResult.Skip = false;
                return(resolveResult);
            }
        }
예제 #13
0
        public async Task <ResolveFieldResult <object> > ResolveField(ExecutionContext context, ObjectGraphType parentType, object source, Fields fields)
        {
            context.CancellationToken.ThrowIfCancellationRequested();

            var resolveResult = new ResolveFieldResult <object>
            {
                Skip = false
            };

            var field = fields.First();

            var fieldDefinition = GetFieldDefinition(context.Schema, parentType, field);

            if (fieldDefinition == null)
            {
                resolveResult.Skip = true;
                return(resolveResult);
            }

            var arguments = GetArgumentValues(context.Schema, fieldDefinition.Arguments, field.Arguments, context.Variables);

            Func <ResolveFieldContext, object> defaultResolve =
                ctx => ctx.Source != null
                    ? GetProperyValue(ctx.Source, ctx.FieldAst.Name)
                    : null;

            try
            {
                var resolveContext = new ResolveFieldContext();
                resolveContext.FieldName         = field.Name;
                resolveContext.FieldAst          = field;
                resolveContext.FieldDefinition   = fieldDefinition;
                resolveContext.ReturnType        = context.Schema.FindType(fieldDefinition.Type);
                resolveContext.ParentType        = parentType;
                resolveContext.Arguments         = arguments;
                resolveContext.Source            = source;
                resolveContext.Schema            = context.Schema;
                resolveContext.Fragments         = context.Fragments;
                resolveContext.RootValue         = context.RootValue;
                resolveContext.Operation         = context.Operation;
                resolveContext.Variables         = context.Variables;
                resolveContext.CancellationToken = context.CancellationToken;
                var resolve = fieldDefinition.Resolve ?? defaultResolve;
                var result  = resolve(resolveContext);

                if (result is Task)
                {
                    var   task = result as Task;
                    await task;

                    result = GetProperyValue(task, "Result");
                }

                if (parentType is __Field && result is Type)
                {
                    result = context.Schema.FindType(result as Type);
                }

                resolveResult.Value = await CompleteValue(context, context.Schema.FindType(fieldDefinition.Type), fields, result);

                return(resolveResult);
            }
            catch (Exception exc)
            {
                var error = new ExecutionError("Error trying to resolve {0}.".ToFormat(field.Name), exc);
                error.AddLocation(field.SourceLocation.Line, field.SourceLocation.Column);
                context.Errors.Add(error);
                resolveResult.Skip = false;
                return(resolveResult);
            }
        }
예제 #14
0
 /// <summary>
 /// Adds the specified error to <see cref="Errors"/>.
 /// </summary>
 /// <returns>Reference to this.</returns>
 public ExecutionResult AddError(ExecutionError error)
 {
     (Errors ??= new ExecutionErrors()).Add(error);
     return(this);
 }