graphql 1.8.4 → 1.8.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/templates/graphql_controller.erb +10 -0
  3. data/lib/graphql/compatibility/schema_parser_specification.rb +398 -0
  4. data/lib/graphql/execution/execute.rb +24 -18
  5. data/lib/graphql/execution/lazy.rb +14 -1
  6. data/lib/graphql/introspection/type_type.rb +1 -1
  7. data/lib/graphql/language/lexer.rb +68 -42
  8. data/lib/graphql/language/lexer.rl +2 -0
  9. data/lib/graphql/language/nodes.rb +98 -0
  10. data/lib/graphql/language/parser.rb +1050 -770
  11. data/lib/graphql/language/parser.y +50 -2
  12. data/lib/graphql/object_type.rb +4 -0
  13. data/lib/graphql/query.rb +3 -1
  14. data/lib/graphql/query/variables.rb +1 -1
  15. data/lib/graphql/schema.rb +10 -2
  16. data/lib/graphql/schema/input_object.rb +1 -1
  17. data/lib/graphql/schema/interface.rb +6 -0
  18. data/lib/graphql/schema/member/has_arguments.rb +1 -0
  19. data/lib/graphql/schema/member/instrumentation.rb +21 -16
  20. data/lib/graphql/schema/mutation.rb +1 -1
  21. data/lib/graphql/schema/object.rb +7 -2
  22. data/lib/graphql/schema/possible_types.rb +1 -1
  23. data/lib/graphql/schema/resolver.rb +210 -1
  24. data/lib/graphql/schema/validation.rb +1 -1
  25. data/lib/graphql/static_validation/message.rb +5 -1
  26. data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +9 -0
  27. data/lib/graphql/type_kinds.rb +9 -6
  28. data/lib/graphql/types.rb +1 -0
  29. data/lib/graphql/types/iso_8601_date_time.rb +1 -5
  30. data/lib/graphql/unauthorized_error.rb +7 -2
  31. data/lib/graphql/version.rb +1 -1
  32. data/spec/generators/graphql/install_generator_spec.rb +12 -2
  33. data/spec/graphql/authorization_spec.rb +80 -1
  34. data/spec/graphql/directive_spec.rb +42 -0
  35. data/spec/graphql/execution_error_spec.rb +1 -1
  36. data/spec/graphql/query_spec.rb +14 -0
  37. data/spec/graphql/schema/interface_spec.rb +14 -0
  38. data/spec/graphql/schema/object_spec.rb +41 -1
  39. data/spec/graphql/schema/relay_classic_mutation_spec.rb +47 -0
  40. data/spec/graphql/schema/resolver_spec.rb +182 -8
  41. data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +6 -5
  42. data/spec/graphql/static_validation/rules/no_definitions_are_present_spec.rb +34 -0
  43. data/spec/graphql/static_validation/validator_spec.rb +15 -0
  44. data/spec/support/jazz.rb +36 -1
  45. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 879e9096d14bb82f2c28f57c60d34e66c6706181
4
- data.tar.gz: c39e6b2c81303fba7c2dfa1527932af7d8eb9d31
3
+ metadata.gz: 2d2c09e6e6d782f0eb3cbb46086cd63e52fa26d1
4
+ data.tar.gz: 34f2ed0c60277b31b0ade93428a48bb77dc4b52e
5
5
  SHA512:
6
- metadata.gz: 79d69e540d7cb3063ce6fea65286f0e66634edeced066930cbc63de169eb9f2a53412f606aacfbf02e28fccfd11781122e95cc31ee234073c6b0f3246c7ac26e
7
- data.tar.gz: 4fe1822b9f021f064a2ba383c65a8c889a4acd08927f0c99ed9d9e473890474c3529afa97ed5cb95fd4f67f5d7754b595cdd654734a2fa595ecfebebeb4ff2a8
6
+ metadata.gz: 91ca8e91bd60c9595113ed6f482a2178d4a56dec6d5d05d08755beaac8f9dac489b7ce952f43e8d585a9d25d0a189684ea207604231bf207254f53af821e964d
7
+ data.tar.gz: 9ce5edd8f2965b7a373aa8f9f7eafac03fc23e241f0bd0f13267accc3c265151b54ac84f70b26edd877e4b198fd2fd17bbd4792a1dcb9c2afc8ceb64ee4b9692
@@ -9,6 +9,9 @@ class GraphqlController < ApplicationController
9
9
  }
10
10
  result = <%= schema_name %>.execute(query, variables: variables, context: context, operation_name: operation_name)
11
11
  render json: result
12
+ rescue => e
13
+ raise e unless Rails.env.development?
14
+ handle_error_in_development e
12
15
  end
13
16
 
14
17
  private
@@ -30,4 +33,11 @@ class GraphqlController < ApplicationController
30
33
  raise ArgumentError, "Unexpected parameter: #{ambiguous_param}"
31
34
  end
32
35
  end
36
+
37
+ def handle_error_in_development(e)
38
+ logger.error e.message
39
+ logger.error e.backtrace.join("\n")
40
+
41
+ render json: { error: { message: e.message, backtrace: e.backtrace }, data: {} }, status: 500
42
+ end
33
43
  end
@@ -192,6 +192,404 @@ module GraphQL
192
192
  assert_equal 'SubscriptionRoot', schema.subscription
193
193
  end
194
194
 
195
+ def test_it_parses_schema_extensions
196
+ document = parse('
197
+ extend schema {
198
+ query: QueryRoot
199
+ mutation: MutationRoot
200
+ subscription: SubscriptionRoot
201
+ }
202
+ ')
203
+
204
+ schema_extension = document.definitions.first
205
+ assert_equal GraphQL::Language::Nodes::SchemaExtension, schema_extension.class
206
+ assert_equal [2, 15], schema_extension.position
207
+
208
+ assert_equal 'QueryRoot', schema_extension.query
209
+ assert_equal 'MutationRoot', schema_extension.mutation
210
+ assert_equal 'SubscriptionRoot', schema_extension.subscription
211
+ end
212
+
213
+ def test_it_parses_schema_extensions_with_directives
214
+ document = parse('
215
+ extend schema @something {
216
+ query: QueryRoot
217
+ }
218
+ ')
219
+
220
+ schema_extension = document.definitions.first
221
+ assert_equal GraphQL::Language::Nodes::SchemaExtension, schema_extension.class
222
+
223
+ assert_equal 1, schema_extension.directives.length
224
+ assert_equal GraphQL::Language::Nodes::Directive, schema_extension.directives.first.class
225
+ assert_equal 'something', schema_extension.directives.first.name
226
+
227
+ assert_equal 'QueryRoot', schema_extension.query
228
+ assert_equal nil, schema_extension.mutation
229
+ assert_equal nil, schema_extension.subscription
230
+ end
231
+
232
+ def test_it_parses_schema_extensions_with_only_directives
233
+ document = parse('
234
+ extend schema @something
235
+ ')
236
+
237
+ schema_extension = document.definitions.first
238
+ assert_equal GraphQL::Language::Nodes::SchemaExtension, schema_extension.class
239
+
240
+ assert_equal 1, schema_extension.directives.length
241
+ assert_equal GraphQL::Language::Nodes::Directive, schema_extension.directives.first.class
242
+ assert_equal 'something', schema_extension.directives.first.name
243
+
244
+ assert_equal nil, schema_extension.query
245
+ assert_equal nil, schema_extension.mutation
246
+ assert_equal nil, schema_extension.subscription
247
+ end
248
+
249
+ def test_it_parses_scalar_extensions
250
+ document = parse('
251
+ extend scalar Date @something @somethingElse
252
+ ')
253
+
254
+ scalar_extension = document.definitions.first
255
+ assert_equal GraphQL::Language::Nodes::ScalarTypeExtension, scalar_extension.class
256
+ assert_equal 'Date', scalar_extension.name
257
+ assert_equal [2, 15], scalar_extension.position
258
+
259
+ assert_equal 2, scalar_extension.directives.length
260
+ assert_equal GraphQL::Language::Nodes::Directive, scalar_extension.directives.first.class
261
+ assert_equal 'something', scalar_extension.directives.first.name
262
+ assert_equal GraphQL::Language::Nodes::Directive, scalar_extension.directives.last.class
263
+ assert_equal 'somethingElse', scalar_extension.directives.last.name
264
+ end
265
+
266
+ def test_it_parses_object_type_extensions_with_field_definitions
267
+ document = parse('
268
+ extend type User {
269
+ login: String!
270
+ }
271
+ ')
272
+
273
+ object_type_extension = document.definitions.first
274
+ assert_equal GraphQL::Language::Nodes::ObjectTypeExtension, object_type_extension.class
275
+ assert_equal 'User', object_type_extension.name
276
+ assert_equal [2, 15], object_type_extension.position
277
+
278
+ assert_equal 1, object_type_extension.fields.length
279
+ assert_equal GraphQL::Language::Nodes::FieldDefinition, object_type_extension.fields.first.class
280
+ end
281
+
282
+ def test_it_parses_object_type_extensions_with_field_definitions_and_directives
283
+ document = parse('
284
+ extend type User @deprecated {
285
+ login: String!
286
+ }
287
+ ')
288
+
289
+ object_type_extension = document.definitions.first
290
+ assert_equal GraphQL::Language::Nodes::ObjectTypeExtension, object_type_extension.class
291
+ assert_equal 'User', object_type_extension.name
292
+ assert_equal [2, 15], object_type_extension.position
293
+
294
+ assert_equal 1, object_type_extension.fields.length
295
+ assert_equal GraphQL::Language::Nodes::FieldDefinition, object_type_extension.fields.first.class
296
+
297
+ assert_equal 1, object_type_extension.directives.length
298
+ assert_equal GraphQL::Language::Nodes::Directive, object_type_extension.directives.first.class
299
+ end
300
+
301
+ def test_it_parses_object_type_extensions_with_field_definitions_and_implements
302
+ document = parse('
303
+ extend type User implements Node {
304
+ login: String!
305
+ }
306
+ ')
307
+
308
+ object_type_extension = document.definitions.first
309
+ assert_equal GraphQL::Language::Nodes::ObjectTypeExtension, object_type_extension.class
310
+ assert_equal 'User', object_type_extension.name
311
+ assert_equal [2, 15], object_type_extension.position
312
+
313
+ assert_equal 1, object_type_extension.fields.length
314
+ assert_equal GraphQL::Language::Nodes::FieldDefinition, object_type_extension.fields.first.class
315
+
316
+ assert_equal 1, object_type_extension.interfaces.length
317
+ assert_equal GraphQL::Language::Nodes::TypeName, object_type_extension.interfaces.first.class
318
+ end
319
+
320
+ def test_it_parses_object_type_extensions_with_only_directives
321
+ document = parse('
322
+ extend type User @deprecated
323
+ ')
324
+
325
+ object_type_extension = document.definitions.first
326
+ assert_equal GraphQL::Language::Nodes::ObjectTypeExtension, object_type_extension.class
327
+ assert_equal 'User', object_type_extension.name
328
+ assert_equal [2, 15], object_type_extension.position
329
+
330
+ assert_equal 1, object_type_extension.directives.length
331
+ assert_equal GraphQL::Language::Nodes::Directive, object_type_extension.directives.first.class
332
+ assert_equal 'deprecated', object_type_extension.directives.first.name
333
+ end
334
+
335
+ def test_it_parses_object_type_extensions_with_implements_and_directives
336
+ document = parse('
337
+ extend type User implements Node @deprecated
338
+ ')
339
+
340
+ object_type_extension = document.definitions.first
341
+ assert_equal GraphQL::Language::Nodes::ObjectTypeExtension, object_type_extension.class
342
+ assert_equal 'User', object_type_extension.name
343
+ assert_equal [2, 15], object_type_extension.position
344
+
345
+ assert_equal 1, object_type_extension.directives.length
346
+ assert_equal GraphQL::Language::Nodes::Directive, object_type_extension.directives.first.class
347
+ assert_equal 'deprecated', object_type_extension.directives.first.name
348
+
349
+ assert_equal 1, object_type_extension.interfaces.length
350
+ assert_equal GraphQL::Language::Nodes::TypeName, object_type_extension.interfaces.first.class
351
+ assert_equal 'Node', object_type_extension.interfaces.first.name
352
+ end
353
+
354
+ def test_it_parses_object_type_extensions_with_only_implements
355
+ document = parse('
356
+ extend type User implements Node
357
+ ')
358
+
359
+ object_type_extension = document.definitions.first
360
+ assert_equal GraphQL::Language::Nodes::ObjectTypeExtension, object_type_extension.class
361
+ assert_equal 'User', object_type_extension.name
362
+ assert_equal [2, 15], object_type_extension.position
363
+
364
+ assert_equal 1, object_type_extension.interfaces.length
365
+ assert_equal GraphQL::Language::Nodes::TypeName, object_type_extension.interfaces.first.class
366
+ assert_equal 'Node', object_type_extension.interfaces.first.name
367
+ end
368
+
369
+ def test_it_parses_interface_type_extensions_with_directives_and_fields
370
+ document = parse('
371
+ extend interface Node @directive {
372
+ field: String
373
+ }
374
+ ')
375
+
376
+ interface_type_extension = document.definitions.first
377
+ assert_equal GraphQL::Language::Nodes::InterfaceTypeExtension, interface_type_extension.class
378
+ assert_equal 'Node', interface_type_extension.name
379
+ assert_equal [2, 15], interface_type_extension.position
380
+
381
+ assert_equal 1, interface_type_extension.directives.length
382
+ assert_equal GraphQL::Language::Nodes::Directive, interface_type_extension.directives.first.class
383
+ assert_equal 'directive', interface_type_extension.directives.first.name
384
+
385
+ assert_equal 1, interface_type_extension.fields.length
386
+ assert_equal GraphQL::Language::Nodes::FieldDefinition, interface_type_extension.fields.first.class
387
+ assert_equal 'field', interface_type_extension.fields.first.name
388
+ end
389
+
390
+ def test_it_parses_interface_type_extensions_with_fields
391
+ document = parse('
392
+ extend interface Node {
393
+ field: String
394
+ }
395
+ ')
396
+
397
+ interface_type_extension = document.definitions.first
398
+ assert_equal GraphQL::Language::Nodes::InterfaceTypeExtension, interface_type_extension.class
399
+ assert_equal 'Node', interface_type_extension.name
400
+ assert_equal [2, 15], interface_type_extension.position
401
+
402
+ assert_equal 0, interface_type_extension.directives.length
403
+
404
+ assert_equal 1, interface_type_extension.fields.length
405
+ assert_equal GraphQL::Language::Nodes::FieldDefinition, interface_type_extension.fields.first.class
406
+ assert_equal 'field', interface_type_extension.fields.first.name
407
+ end
408
+
409
+ def test_it_parses_interface_type_extensions_with_directives
410
+ document = parse('
411
+ extend interface Node @directive
412
+ ')
413
+
414
+ interface_type_extension = document.definitions.first
415
+ assert_equal GraphQL::Language::Nodes::InterfaceTypeExtension, interface_type_extension.class
416
+ assert_equal 'Node', interface_type_extension.name
417
+ assert_equal [2, 15], interface_type_extension.position
418
+
419
+ assert_equal 1, interface_type_extension.directives.length
420
+ assert_equal GraphQL::Language::Nodes::Directive, interface_type_extension.directives.first.class
421
+ assert_equal 'directive', interface_type_extension.directives.first.name
422
+ end
423
+
424
+ def test_it_parses_union_type_extension_with_union_members
425
+ document = parse('
426
+ extend union BagOfThings = A | B
427
+ ')
428
+
429
+ union_type_extension = document.definitions.first
430
+ assert_equal GraphQL::Language::Nodes::UnionTypeExtension, union_type_extension.class
431
+ assert_equal 'BagOfThings', union_type_extension.name
432
+ assert_equal [2, 15], union_type_extension.position
433
+
434
+ assert_equal 0, union_type_extension.directives.length
435
+
436
+ assert_equal 2, union_type_extension.types.length
437
+ assert_equal GraphQL::Language::Nodes::TypeName, union_type_extension.types.first.class
438
+ assert_equal 'A', union_type_extension.types.first.name
439
+ end
440
+
441
+ def test_it_parses_union_type_extension_with_directives_and_union_members
442
+ document = parse('
443
+ extend union BagOfThings @directive = A | B
444
+ ')
445
+
446
+ union_type_extension = document.definitions.first
447
+ assert_equal GraphQL::Language::Nodes::UnionTypeExtension, union_type_extension.class
448
+ assert_equal 'BagOfThings', union_type_extension.name
449
+ assert_equal [2, 15], union_type_extension.position
450
+
451
+ assert_equal 1, union_type_extension.directives.length
452
+ assert_equal GraphQL::Language::Nodes::Directive, union_type_extension.directives.first.class
453
+ assert_equal 'directive', union_type_extension.directives.first.name
454
+
455
+ assert_equal 2, union_type_extension.types.length
456
+ assert_equal GraphQL::Language::Nodes::TypeName, union_type_extension.types.first.class
457
+ assert_equal 'A', union_type_extension.types.first.name
458
+ end
459
+
460
+ def test_it_parses_union_type_extension_with_directives
461
+ document = parse('
462
+ extend union BagOfThings @directive
463
+ ')
464
+
465
+ union_type_extension = document.definitions.first
466
+ assert_equal GraphQL::Language::Nodes::UnionTypeExtension, union_type_extension.class
467
+ assert_equal 'BagOfThings', union_type_extension.name
468
+ assert_equal [2, 15], union_type_extension.position
469
+
470
+ assert_equal 1, union_type_extension.directives.length
471
+ assert_equal GraphQL::Language::Nodes::Directive, union_type_extension.directives.first.class
472
+ assert_equal 'directive', union_type_extension.directives.first.name
473
+
474
+ assert_equal 0, union_type_extension.types.length
475
+ end
476
+
477
+ def test_it_parses_enum_type_extension_with_values
478
+ document = parse('
479
+ extend enum Status {
480
+ DRAFT
481
+ PUBLISHED
482
+ }
483
+ ')
484
+
485
+ enum_type_extension = document.definitions.first
486
+ assert_equal GraphQL::Language::Nodes::EnumTypeExtension, enum_type_extension.class
487
+ assert_equal 'Status', enum_type_extension.name
488
+ assert_equal [2, 15], enum_type_extension.position
489
+
490
+ assert_equal 0, enum_type_extension.directives.length
491
+
492
+ assert_equal 2, enum_type_extension.values.length
493
+ assert_equal GraphQL::Language::Nodes::EnumValueDefinition, enum_type_extension.values.first.class
494
+ assert_equal 'DRAFT', enum_type_extension.values.first.name
495
+ end
496
+
497
+ def test_it_parses_enum_type_extension_with_directives_and_values
498
+ document = parse('
499
+ extend enum Status @directive {
500
+ DRAFT
501
+ PUBLISHED
502
+ }
503
+ ')
504
+
505
+ enum_type_extension = document.definitions.first
506
+ assert_equal GraphQL::Language::Nodes::EnumTypeExtension, enum_type_extension.class
507
+ assert_equal 'Status', enum_type_extension.name
508
+ assert_equal [2, 15], enum_type_extension.position
509
+
510
+ assert_equal 1, enum_type_extension.directives.length
511
+ assert_equal GraphQL::Language::Nodes::Directive, enum_type_extension.directives.first.class
512
+ assert_equal 'directive', enum_type_extension.directives.first.name
513
+
514
+ assert_equal 2, enum_type_extension.values.length
515
+ assert_equal GraphQL::Language::Nodes::EnumValueDefinition, enum_type_extension.values.first.class
516
+ assert_equal 'DRAFT', enum_type_extension.values.first.name
517
+ end
518
+
519
+ def test_it_parses_enum_type_extension_with_directives
520
+ document = parse('
521
+ extend enum Status @directive
522
+ ')
523
+
524
+ enum_type_extension = document.definitions.first
525
+ assert_equal GraphQL::Language::Nodes::EnumTypeExtension, enum_type_extension.class
526
+ assert_equal 'Status', enum_type_extension.name
527
+ assert_equal [2, 15], enum_type_extension.position
528
+
529
+ assert_equal 1, enum_type_extension.directives.length
530
+ assert_equal GraphQL::Language::Nodes::Directive, enum_type_extension.directives.first.class
531
+ assert_equal 'directive', enum_type_extension.directives.first.name
532
+
533
+ assert_equal 0, enum_type_extension.values.length
534
+ end
535
+
536
+ def test_it_parses_input_object_type_extension_with_fields
537
+ document = parse('
538
+ extend input UserInput {
539
+ login: String!
540
+ }
541
+ ')
542
+
543
+ input_object_type_extension = document.definitions.first
544
+ assert_equal GraphQL::Language::Nodes::InputObjectTypeExtension, input_object_type_extension.class
545
+ assert_equal 'UserInput', input_object_type_extension.name
546
+ assert_equal [2, 15], input_object_type_extension.position
547
+
548
+ assert_equal 1, input_object_type_extension.fields.length
549
+ assert_equal GraphQL::Language::Nodes::InputValueDefinition, input_object_type_extension.fields.first.class
550
+ assert_equal 'login', input_object_type_extension.fields.first.name
551
+
552
+ assert_equal 0, input_object_type_extension.directives.length
553
+ end
554
+
555
+ def test_it_parses_input_object_type_extension_with_directives_and_fields
556
+ document = parse('
557
+ extend input UserInput @deprecated {
558
+ login: String!
559
+ }
560
+ ')
561
+
562
+ input_object_type_extension = document.definitions.first
563
+ assert_equal GraphQL::Language::Nodes::InputObjectTypeExtension, input_object_type_extension.class
564
+ assert_equal 'UserInput', input_object_type_extension.name
565
+ assert_equal [2, 15], input_object_type_extension.position
566
+
567
+ assert_equal 1, input_object_type_extension.fields.length
568
+ assert_equal GraphQL::Language::Nodes::InputValueDefinition, input_object_type_extension.fields.first.class
569
+ assert_equal 'login', input_object_type_extension.fields.first.name
570
+
571
+ assert_equal 1, input_object_type_extension.directives.length
572
+ assert_equal GraphQL::Language::Nodes::Directive, input_object_type_extension.directives.first.class
573
+ assert_equal 'deprecated', input_object_type_extension.directives.first.name
574
+ end
575
+
576
+ def test_it_parses_input_object_type_extension_with_directives
577
+ document = parse('
578
+ extend input UserInput @deprecated
579
+ ')
580
+
581
+ input_object_type_extension = document.definitions.first
582
+ assert_equal GraphQL::Language::Nodes::InputObjectTypeExtension, input_object_type_extension.class
583
+ assert_equal 'UserInput', input_object_type_extension.name
584
+ assert_equal [2, 15], input_object_type_extension.position
585
+
586
+ assert_equal 0, input_object_type_extension.fields.length
587
+
588
+ assert_equal 1, input_object_type_extension.directives.length
589
+ assert_equal GraphQL::Language::Nodes::Directive, input_object_type_extension.directives.first.class
590
+ assert_equal 'deprecated', input_object_type_extension.directives.first.name
591
+ end
592
+
195
593
  def test_it_parses_whole_definition_with_descriptions
196
594
  document = parse(SCHEMA_DEFINITION_STRING)
197
595
 
@@ -102,9 +102,13 @@ module GraphQL
102
102
  field = field_ctx.field
103
103
 
104
104
  raw_value = begin
105
- arguments = query.arguments_for(irep_node, field)
106
- field_ctx.trace("execute_field", { context: field_ctx }) do
107
- field_ctx.schema.middleware.invoke([parent_type, object, field, arguments, field_ctx])
105
+ begin
106
+ arguments = query.arguments_for(irep_node, field)
107
+ field_ctx.trace("execute_field", { context: field_ctx }) do
108
+ field_ctx.schema.middleware.invoke([parent_type, object, field, arguments, field_ctx])
109
+ end
110
+ rescue GraphQL::UnauthorizedError => err
111
+ field_ctx.schema.unauthorized_object(err)
108
112
  end
109
113
  rescue GraphQL::ExecutionError => err
110
114
  err
@@ -123,10 +127,10 @@ module GraphQL
123
127
  err
124
128
  end
125
129
  }
126
- continue_or_wait(inner_value, arguments, field_ctx)
130
+ continue_or_wait(inner_value, field_ctx.type, field_ctx)
127
131
  }
128
132
  else
129
- continue_or_wait(raw_value, arguments, field_ctx)
133
+ continue_or_wait(raw_value, field_ctx.type, field_ctx)
130
134
  end
131
135
  end
132
136
 
@@ -137,7 +141,7 @@ module GraphQL
137
141
  #
138
142
  # If the returned object is finished, continue to coerce
139
143
  # and resolve child fields
140
- def continue_or_wait(raw_value, arguments, field_ctx)
144
+ def continue_or_wait(raw_value, field_type, field_ctx)
141
145
  if (lazy_method = field_ctx.schema.lazy_method_name(raw_value))
142
146
  field_ctx.value = Execution::Lazy.new {
143
147
  inner_value = begin
@@ -150,14 +154,14 @@ module GraphQL
150
154
  err
151
155
  end
152
156
 
153
- field_ctx.value = continue_or_wait(inner_value, arguments, field_ctx)
157
+ field_ctx.value = continue_or_wait(inner_value, field_type, field_ctx)
154
158
  }
155
159
  else
156
- field_ctx.value = continue_resolve_field(raw_value, field_ctx)
160
+ field_ctx.value = continue_resolve_field(raw_value, field_type, field_ctx)
157
161
  end
158
162
  end
159
163
 
160
- def continue_resolve_field(raw_value, field_ctx)
164
+ def continue_resolve_field(raw_value, field_type, field_ctx)
161
165
  if field_ctx.parent.invalid_null?
162
166
  return nil
163
167
  end
@@ -169,19 +173,22 @@ module GraphQL
169
173
  raw_value.path = field_ctx.path
170
174
  query.context.errors.push(raw_value)
171
175
  when Array
172
- list_errors = raw_value.each_with_index.select { |value, _| value.is_a?(GraphQL::ExecutionError) }
173
- if list_errors.any?
174
- list_errors.each do |error, index|
175
- error.ast_node = field_ctx.ast_node
176
- error.path = field_ctx.path + [index]
177
- query.context.errors.push(error)
176
+ if !field_type.list?
177
+ # List type errors are handled above, this is for the case of fields returning an array of errors
178
+ list_errors = raw_value.each_with_index.select { |value, _| value.is_a?(GraphQL::ExecutionError) }
179
+ if list_errors.any?
180
+ list_errors.each do |error, index|
181
+ error.ast_node = field_ctx.ast_node
182
+ error.path = field_ctx.path + [index]
183
+ query.context.errors.push(error)
184
+ end
178
185
  end
179
186
  end
180
187
  end
181
188
 
182
189
  resolve_value(
183
190
  raw_value,
184
- field_ctx.type,
191
+ field_type,
185
192
  field_ctx,
186
193
  )
187
194
  end
@@ -229,7 +236,7 @@ module GraphQL
229
236
  irep_node: field_ctx.irep_node,
230
237
  )
231
238
 
232
- inner_result = resolve_value(
239
+ inner_result = continue_or_wait(
233
240
  inner_value,
234
241
  inner_type,
235
242
  inner_ctx,
@@ -237,7 +244,6 @@ module GraphQL
237
244
 
238
245
  return PROPAGATE_NULL if inner_result == PROPAGATE_NULL
239
246
 
240
- inner_ctx.value = inner_result
241
247
  result << inner_ctx
242
248
  i += 1
243
249
  end