graphql 1.8.4 → 1.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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