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)); }
public async Task <object> CompleteValue(ExecutionContext context, GraphType fieldType, Fields fields, object result) { var nonNullType = fieldType as NonNullGraphType; if (nonNullType != null) { var type = context.Schema.FindType(nonNullType.Type); var completed = await CompleteValue(context, type, fields, result); if (completed == null) { var field = fields != null?fields.FirstOrDefault() : null; var fieldName = field != null ? field.Name : null; throw new ExecutionError("Cannot return null for non-null type. Field: {0}, Type: {1}!." .ToFormat(fieldName, type.Name)); } return(completed); } if (result == null) { return(null); } if (fieldType is ScalarGraphType) { var scalarType = fieldType as ScalarGraphType; var coercedValue = scalarType.Coerce(result); return(coercedValue); } if (fieldType is ListGraphType) { var list = result as IEnumerable; if (list == null) { throw new ExecutionError("User error: expected an IEnumerable list though did not find one."); } var listType = fieldType as ListGraphType; var itemType = context.Schema.FindType(listType.Type); var results = await list.MapAsync(async item => { return(await CompleteValue(context, itemType, fields, item)); }); return(results); } var objectType = fieldType as ObjectGraphType; if (fieldType is InterfaceGraphType) { var interfaceType = fieldType as InterfaceGraphType; objectType = interfaceType.ResolveType(result); } if (objectType == null) { return(null); } var subFields = new Dictionary <string, Fields>(); fields.Apply(field => { subFields = CollectFields(context, objectType, field.Selections, subFields); }); return(await ExecuteFields(context, objectType, result, subFields)); }