Skip to content

Commit 508bd86

Browse files
author
GravlLift
committed
Merge remote-tracking branch 'lukemurray/master'
2 parents 984f483 + a8c76e1 commit 508bd86

19 files changed

Lines changed: 131 additions & 63 deletions

‎CHANGELOG.md‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
# 0.68.0
2+
- Fix issue where `FieldNamer` was not being consistently used. Thanks @AnderssonPeter
3+
- Make sure we include inner exceptions on errors. Thanks @AnderssonPeter
4+
5+
# 0.67.0
6+
- As per GraphQL spec commas are optional (previously EntityGraphQL expected them in field/mutation arguments)
7+
8+
*Breaking changes*
9+
- errors property on query result should not be present on the response if there are no errors per the graphQL specification.
10+
111
# 0.66.1
212
- Fix bug with using `WithService()` when you require the schema context service again to create a link between services
313

‎src/EntityGraphQL/Compiler/GraphQLCompiler.cs‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,17 @@ public GraphQLResultNode Compile(QueryRequest request, ClaimsIdentity claims = n
6060
{
6161
if (pce.InnerException is NoViableAltException nve)
6262
{
63-
throw new EntityGraphQLCompilerException($"Error: line {nve.OffendingToken.Line}:{nve.OffendingToken.Column} no viable alternative at input '{nve.OffendingToken.Text}'");
63+
throw new EntityGraphQLCompilerException($"Error: line {nve.OffendingToken.Line}:{nve.OffendingToken.Column} no viable alternative at input '{nve.OffendingToken.Text}'", pce);
6464
}
6565
else if (pce.InnerException is InputMismatchException ime)
6666
{
6767
var expecting = string.Join(", ", ime.GetExpectedTokens());
68-
throw new EntityGraphQLCompilerException($"Error: line {ime.OffendingToken.Line}:{ime.OffendingToken.Column} extraneous input '{ime.OffendingToken.Text}' expecting {expecting}");
68+
throw new EntityGraphQLCompilerException($"Error: line {ime.OffendingToken.Line}:{ime.OffendingToken.Column} extraneous input '{ime.OffendingToken.Text}' expecting {expecting}", pce);
6969
}
7070
System.Console.WriteLine(pce.InnerException.GetType());
71-
throw new EntityGraphQLCompilerException(pce.InnerException.Message);
71+
throw new EntityGraphQLCompilerException(pce.InnerException.Message, pce);
7272
}
73-
throw new EntityGraphQLCompilerException(pce.Message);
73+
throw new EntityGraphQLCompilerException(pce.Message, pce);
7474
}
7575
}
7676
}

‎src/EntityGraphQL/Compiler/GraphQLMutationNode.cs‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,36 @@ public class GraphQLMutationNode : GraphQLExecutableNode, IGraphQLBaseNode
1515
private readonly MutationType mutationType;
1616
private readonly Dictionary<string, ExpressionResult> args;
1717
private readonly GraphQLQueryNode resultSelection;
18+
private readonly Func<string, string> fieldNamer;
1819

1920
public string Name { get => mutationType.Name; set => throw new NotImplementedException(); }
2021
public ParameterExpression FieldParameter => throw new NotImplementedException();
2122
public IEnumerable<Type> Services => throw new NotImplementedException();
2223

2324
public IReadOnlyDictionary<ParameterExpression, object> ConstantParameters => resultSelection?.ConstantParameters ?? new Dictionary<ParameterExpression, object>();
2425

25-
public GraphQLMutationNode(MutationType mutationType, Dictionary<string, ExpressionResult> args, GraphQLQueryNode resultSelection)
26+
public GraphQLMutationNode(MutationType mutationType, Dictionary<string, ExpressionResult> args, GraphQLQueryNode resultSelection, Func<string, string> fieldNamer)
2627
{
2728
this.mutationType = mutationType;
2829
this.args = args;
2930
this.resultSelection = resultSelection;
31+
this.fieldNamer = fieldNamer;
3032
}
3133

3234
public ExpressionResult GetNodeExpression(object contextValue, IServiceProvider serviceProvider)
3335
{
3436
throw new NotImplementedException();
3537
}
3638

37-
private async Task<object> ExecuteMutationAsync<TContext>(TContext context, GraphQLValidator validator, IServiceProvider serviceProvider)
39+
private async Task<object> ExecuteMutationAsync<TContext>(TContext context, GraphQLValidator validator, IServiceProvider serviceProvider, Func<string, string> fieldNamer)
3840
{
3941
try
4042
{
41-
return await mutationType.CallAsync(context, args, validator, serviceProvider);
43+
return await mutationType.CallAsync(context, args, validator, serviceProvider, fieldNamer);
4244
}
4345
catch (EntityQuerySchemaException e)
4446
{
45-
throw new EntityQuerySchemaException($"Error applying mutation: {e.Message}");
47+
throw new EntityQuerySchemaException($"Error applying mutation: {e.Message}", e);
4648
}
4749
}
4850

@@ -56,7 +58,7 @@ private async Task<object> ExecuteMutationAsync<TContext>(TContext context, Grap
5658
public override async Task<object> ExecuteAsync<TContext>(TContext context, GraphQLValidator validator, IServiceProvider serviceProvider)
5759
{
5860
// run the mutation to get the context for the query select
59-
var result = await ExecuteMutationAsync(context, validator, serviceProvider);
61+
var result = await ExecuteMutationAsync(context, validator, serviceProvider, fieldNamer);
6062
if (result == null)
6163
return null;
6264
if (typeof(LambdaExpression).IsAssignableFrom(result.GetType()))

‎src/EntityGraphQL/Compiler/GraphQLVisitor.cs‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,13 @@ public override IGraphQLBaseNode VisitField(EntityGraphQLParser.FieldContext con
5959
currentExpressionContext = expContext;
6060
var select = ParseFieldSelect(expContext, actualFieldName, context.select);
6161
currentExpressionContext = oldContext;
62-
return new GraphQLMutationNode(mutationType, args, (GraphQLQueryNode)select);
62+
return new GraphQLMutationNode(mutationType, args, (GraphQLQueryNode)select, schemaProvider.SchemaFieldNamer);
6363
}
6464
else
6565
{
6666
var resultName = alias ?? actualFieldName;
6767

68-
return new GraphQLMutationNode(mutationType, args, null);
68+
return new GraphQLMutationNode(mutationType, args, null, schemaProvider.SchemaFieldNamer);
6969
}
7070
}
7171
else
@@ -177,6 +177,10 @@ public ExpressionResult ParseGqlarg(IField fieldArgumentContext, EntityGraphQLPa
177177
if (context.gqlVar() != null)
178178
{
179179
string varKey = context.gqlVar().GetText().TrimStart('$');
180+
if (variables == null)
181+
{
182+
throw new EntityGraphQLCompilerException($"Missing variable {varKey}");
183+
}
180184
object value = variables.GetValueFor(varKey);
181185
gqlVarValue = (ExpressionResult)Expression.Constant(value);
182186
}

‎src/EntityGraphQL/Compiler/Util/ExpressionUtil.cs‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ public static ExpressionResult MakeCallOnQueryable(string methodName, Type[] gen
1616
{
1717
return (ExpressionResult)Expression.Call(type, methodName, genericTypes, parameters);
1818
}
19-
catch (InvalidOperationException)
19+
catch (InvalidOperationException ex)
2020
{
21-
throw new EntityGraphQLCompilerException($"Could not find extension method {methodName} on types {type}");
21+
throw new EntityGraphQLCompilerException($"Could not find extension method {methodName} on types {type}", ex);
2222
}
2323
}
2424

@@ -29,9 +29,9 @@ public static ExpressionResult MakeCallOnEnumerable(string methodName, Type[] ge
2929
{
3030
return (ExpressionResult)Expression.Call(type, methodName, genericTypes, parameters);
3131
}
32-
catch (InvalidOperationException)
32+
catch (InvalidOperationException ex)
3333
{
34-
throw new EntityGraphQLCompilerException($"Could not find extension method {methodName} on types {type}");
34+
throw new EntityGraphQLCompilerException($"Could not find extension method {methodName} on types {type}", ex);
3535
}
3636
}
3737

‎src/EntityGraphQL/EntityGraphQL.csproj‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<TargetFramework>netstandard1.6</TargetFramework>
44
<AssemblyName>EntityGraphQL</AssemblyName>
55
<PackageId>EntityGraphQL</PackageId>
6-
<PackageVersion>0.66.1</PackageVersion>
6+
<PackageVersion>0.67.0</PackageVersion>
77
<Description>A GraphQL library for .NET Core. Compiles queries into .NET Expressions (LinqProvider) for runtime execution against object graphs. E.g. against an ORM data model (EntityFramework or others) or just an in-memory object.</Description>
88
<Authors>Luke Murray</Authors>
99
<PackageProjectUrl>https://github.com/lukemurray/EntityGraphQL</PackageProjectUrl>

‎src/EntityGraphQL/Grammer/EntityGraphQL.g4‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ mutationKeyword: 'mutation';
4444
subscriptionKeyword: 'subscription';
4545
4646
gqlCall: '(' ws* gqlarguments = gqlargs ws* ')';
47-
gqlargs: gqlarg (ws* ',' ws* gqlarg)*;
48-
gqlTypeDefs: gqlTypeDef (',' ws* gqlTypeDef)*;
47+
gqlargs: gqlarg (ws* ','? ws* gqlarg)*;
48+
gqlTypeDefs: gqlTypeDef (','? ws* gqlTypeDef)*;
4949
gqlTypeDef:
5050
gqlVar ws* ':' ws* (type = identity | arrayType = varArray) required = '!'? (
5151
ws* '=' ws* defaultValue = constant

‎src/EntityGraphQL/LinqQuery/DefaultMethodProvider.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,9 @@ private static ExpressionResult ConvertTypeIfWeCan(string methodName, Expression
180180
{
181181
return (ExpressionResult)Expression.Convert(argExp, expected);
182182
}
183-
catch (Exception)
183+
catch (Exception ex)
184184
{
185-
throw new EntityGraphQLCompilerException($"Method '{methodName}' expects parameter that evaluates to a '{expected}' result but found result type '{argExp.Type}'");
185+
throw new EntityGraphQLCompilerException($"Method '{methodName}' expects parameter that evaluates to a '{expected}' result but found result type '{argExp.Type}'", ex);
186186
}
187187
}
188188
return argExp;

‎src/EntityGraphQL/Schema/ISchemaProvider.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ namespace EntityGraphQL.Schema
1818
/// </summary>
1919
public interface ISchemaProvider
2020
{
21-
Func<MemberInfo, string> SchemaFieldNamer { get; }
21+
Func<string, string> SchemaFieldNamer { get; }
2222
/// The base context type that expression will be built from. For example your DbContext
2323
Type ContextType { get; }
2424

‎src/EntityGraphQL/Schema/MutationType.cs‎

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ namespace EntityGraphQL.Schema
1212
{
1313
public class MutationType : IField
1414
{
15+
private readonly ISchemaProvider schema;
1516
private readonly object mutationClassInstance;
1617
private readonly MethodInfo method;
1718
private readonly Dictionary<string, ArgType> argumentTypes = new Dictionary<string, ArgType>();
@@ -27,7 +28,7 @@ public class MutationType : IField
2728

2829
public GqlTypeInfo ReturnType { get; }
2930

30-
public async Task<object> CallAsync(object context, Dictionary<string, ExpressionResult> gqlRequestArgs, GraphQLValidator validator, IServiceProvider serviceProvider)
31+
public async Task<object> CallAsync(object context, Dictionary<string, ExpressionResult> gqlRequestArgs, GraphQLValidator validator, IServiceProvider serviceProvider, Func<string, string> fieldNamer)
3132
{
3233
// args in the mutation method
3334
var allArgs = new List<object>();
@@ -36,7 +37,7 @@ public async Task<object> CallAsync(object context, Dictionary<string, Expressio
3637
if (gqlRequestArgs != null)
3738
{
3839
// second arg is the arguments for the mutation - required as last arg in the mutation method
39-
argInstance = AssignArgValues(gqlRequestArgs);
40+
argInstance = AssignArgValues(gqlRequestArgs, fieldNamer);
4041
VaildateModelBinding(argInstance, validator);
4142
if (validator.Errors.Any())
4243
return null;
@@ -81,7 +82,7 @@ public async Task<object> CallAsync(object context, Dictionary<string, Expressio
8182
return result;
8283
}
8384

84-
private object AssignArgValues(Dictionary<string, ExpressionResult> gqlRequestArgs)
85+
private object AssignArgValues(Dictionary<string, ExpressionResult> gqlRequestArgs, Func<string, string> fieldNamer)
8586
{
8687
var argInstance = Activator.CreateInstance(this.argInstanceType);
8788
Type argType = this.argInstanceType;
@@ -90,7 +91,7 @@ private object AssignArgValues(Dictionary<string, ExpressionResult> gqlRequestAr
9091
var foundProp = false;
9192
foreach (var prop in argType.GetProperties())
9293
{
93-
var propName = SchemaGenerator.ToCamelCaseStartsLower(prop.Name);
94+
var propName = fieldNamer(prop.Name);
9495
if (key == propName)
9596
{
9697
object value = GetValue(gqlRequestArgs, propName, prop.PropertyType);
@@ -102,7 +103,7 @@ private object AssignArgValues(Dictionary<string, ExpressionResult> gqlRequestAr
102103
{
103104
foreach (var field in argType.GetFields())
104105
{
105-
var fieldName = SchemaGenerator.ToCamelCaseStartsLower(field.Name);
106+
var fieldName = fieldNamer(field.Name);
106107
if (key == fieldName)
107108
{
108109
object value = GetValue(gqlRequestArgs, fieldName, field.FieldType);
@@ -154,8 +155,9 @@ private object GetValue(Dictionary<string, ExpressionResult> gqlRequestArgs, str
154155
return value;
155156
}
156157

157-
public MutationType(ISchemaProvider schema, string methodName, GqlTypeInfo returnType, object mutationClassInstance, MethodInfo method, string description, RequiredClaims authorizeClaims, bool isAsync, Func<MemberInfo, string> fieldNamer)
158+
public MutationType(ISchemaProvider schema, string methodName, GqlTypeInfo returnType, object mutationClassInstance, MethodInfo method, string description, RequiredClaims authorizeClaims, bool isAsync, Func<string, string> fieldNamer)
158159
{
160+
this.schema = schema;
159161
Description = description;
160162
ReturnType = returnType;
161163
this.mutationClassInstance = mutationClassInstance;
@@ -172,13 +174,13 @@ public MutationType(ISchemaProvider schema, string methodName, GqlTypeInfo retur
172174
{
173175
if (GraphQLIgnoreAttribute.ShouldIgnoreMemberFromInput(item))
174176
continue;
175-
argumentTypes.Add(fieldNamer(item), ArgType.FromProperty(schema, item));
177+
argumentTypes.Add(fieldNamer(item.Name), ArgType.FromProperty(schema, item));
176178
}
177179
foreach (var item in argInstanceType.GetFields())
178180
{
179181
if (GraphQLIgnoreAttribute.ShouldIgnoreMemberFromInput(item))
180182
continue;
181-
argumentTypes.Add(fieldNamer(item), ArgType.FromField(schema, item));
183+
argumentTypes.Add(fieldNamer(item.Name), ArgType.FromField(schema, item));
182184
}
183185
}
184186
}

0 commit comments

Comments
 (0)