Skip to content

Commit d6ccf7d

Browse files
AndrewSisleyfredcarle
authored andcommitted
feat: Allow returning of errors from fields thunk (#2)
- Allow returning of errors from fields thunk
1 parent 5853855 commit d6ccf7d

File tree

5 files changed

+54
-26
lines changed

5 files changed

+54
-26
lines changed

definition.go

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ type ObjectConfig struct {
375375
Description string `json:"description"`
376376
}
377377

378-
type FieldsThunk func() Fields
378+
type FieldsThunk func() (Fields, error)
379379

380380
func NewObject(config ObjectConfig) *Object {
381381
objectType := &Object{}
@@ -416,10 +416,11 @@ func (gt *Object) AddFieldConfig(fieldName string, fieldConfig *Field) {
416416
case FieldsThunk:
417417
// if the fields are defined as a thunk when the object is created
418418
// then wrap the thunk in another thunk.
419-
gt.typeConfig.Fields = (FieldsThunk)(func() Fields {
420-
newFields := fields()
419+
gt.typeConfig.Fields = (FieldsThunk)(func() (Fields, error) {
420+
newFields, err := fields()
421+
gt.err = err
421422
newFields[fieldName] = fieldConfig
422-
return newFields
423+
return newFields, err
423424
})
424425
gt.initialisedFields = false
425426
}
@@ -433,22 +434,36 @@ func (gt *Object) Description() string {
433434
func (gt *Object) String() string {
434435
return gt.PrivateName
435436
}
437+
436438
func (gt *Object) Fields() FieldDefinitionMap {
439+
// We discard the returned error to preserve the orignal behaviour
440+
// The error will still be added to the `gt.err` property
441+
m, _ := gt.InitFields()
442+
return m
443+
}
444+
445+
func (gt *Object) InitFields() (FieldDefinitionMap, error) {
437446
if gt.initialisedFields {
438-
return gt.fields
447+
return gt.fields, nil
439448
}
440449

441450
var configureFields Fields
451+
var err error
442452
switch fields := gt.typeConfig.Fields.(type) {
443453
case Fields:
444454
configureFields = fields
445455
case FieldsThunk:
446-
configureFields = fields()
456+
configureFields, err = fields()
457+
}
458+
459+
if err != nil {
460+
gt.err = err
461+
return nil, err
447462
}
448463

449464
gt.fields, gt.err = defineFieldMap(gt, configureFields)
450465
gt.initialisedFields = true
451-
return gt.fields
466+
return gt.fields, nil
452467
}
453468

454469
func (gt *Object) Interfaces() []*Interface {
@@ -753,21 +768,34 @@ func (it *Interface) Description() string {
753768
}
754769

755770
func (it *Interface) Fields() (fields FieldDefinitionMap) {
771+
// We discard the returned error to preserve the orignal behaviour
772+
// The error will still be added to the `gt.err` property
773+
m, _ := it.InitFields()
774+
return m
775+
}
776+
777+
func (it *Interface) InitFields() (FieldDefinitionMap, error) {
756778
if it.initialisedFields {
757-
return it.fields
779+
return it.fields, nil
758780
}
759781

760782
var configureFields Fields
783+
var err error
761784
switch fields := it.typeConfig.Fields.(type) {
762785
case Fields:
763786
configureFields = fields
764787
case FieldsThunk:
765-
configureFields = fields()
788+
configureFields, err = fields()
789+
}
790+
791+
if err != nil {
792+
it.err = err
793+
return nil, err
766794
}
767795

768796
it.fields, it.err = defineFieldMap(it, configureFields)
769797
it.initialisedFields = true
770-
return it.fields
798+
return it.fields, nil
771799
}
772800

773801
func (it *Interface) String() string {

definition_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -604,15 +604,15 @@ func TestTypeSystem_DefinitionExample_IncludesFieldsThunk(t *testing.T) {
604604
var someObject *graphql.Object
605605
someObject = graphql.NewObject(graphql.ObjectConfig{
606606
Name: "SomeObject",
607-
Fields: (graphql.FieldsThunk)(func() graphql.Fields {
607+
Fields: (graphql.FieldsThunk)(func() (graphql.Fields, error) {
608608
return graphql.Fields{
609609
"f": &graphql.Field{
610610
Type: graphql.Int,
611611
},
612612
"s": &graphql.Field{
613613
Type: someObject,
614614
},
615-
}
615+
}, nil
616616
}),
617617
})
618618
fieldMap := someObject.Fields()
@@ -624,15 +624,15 @@ func TestTypeSystem_DefinitionExample_IncludesFieldsThunk(t *testing.T) {
624624
func TestTypeSystem_DefinitionExampe_AllowsCyclicFieldTypes(t *testing.T) {
625625
personType := graphql.NewObject(graphql.ObjectConfig{
626626
Name: "Person",
627-
Fields: (graphql.FieldsThunk)(func() graphql.Fields {
627+
Fields: (graphql.FieldsThunk)(func() (graphql.Fields, error) {
628628
return graphql.Fields{
629629
"name": &graphql.Field{
630630
Type: graphql.String,
631631
},
632632
"bestFriend": &graphql.Field{
633633
Type: personType,
634634
},
635-
}
635+
}, nil
636636
}),
637637
})
638638

executor_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,8 +2146,8 @@ func testErrors(t *testing.T, nameType graphql.Output, extensions map[string]int
21462146

21472147
heroType := graphql.NewObject(graphql.ObjectConfig{
21482148
Name: "Hero",
2149-
Fields: graphql.FieldsThunk(func() graphql.Fields {
2150-
return heroFields
2149+
Fields: graphql.FieldsThunk(func() (graphql.Fields, error) {
2150+
return heroFields, nil
21512151
}),
21522152
})
21532153

rules_overlapping_fields_can_be_merged_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -408,23 +408,23 @@ func init() {
408408
ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {
409409
return stringBoxObject
410410
},
411-
Fields: graphql.FieldsThunk(func() graphql.Fields {
411+
Fields: graphql.FieldsThunk(func() (graphql.Fields, error) {
412412
return graphql.Fields{
413413
"deepBox": &graphql.Field{
414414
Type: someBoxInterface,
415415
},
416416
"unrelatedField": &graphql.Field{
417417
Type: graphql.String,
418418
},
419-
}
419+
}, nil
420420
}),
421421
})
422422
stringBoxObject = graphql.NewObject(graphql.ObjectConfig{
423423
Name: "StringBox",
424424
Interfaces: (graphql.InterfacesThunk)(func() []*graphql.Interface {
425425
return []*graphql.Interface{someBoxInterface}
426426
}),
427-
Fields: graphql.FieldsThunk(func() graphql.Fields {
427+
Fields: graphql.FieldsThunk(func() (graphql.Fields, error) {
428428
return graphql.Fields{
429429
"scalar": &graphql.Field{
430430
Type: graphql.String,
@@ -444,15 +444,15 @@ func init() {
444444
"intBox": &graphql.Field{
445445
Type: intBoxObject,
446446
},
447-
}
447+
}, nil
448448
}),
449449
})
450450
intBoxObject = graphql.NewObject(graphql.ObjectConfig{
451451
Name: "IntBox",
452452
Interfaces: (graphql.InterfacesThunk)(func() []*graphql.Interface {
453453
return []*graphql.Interface{someBoxInterface}
454454
}),
455-
Fields: graphql.FieldsThunk(func() graphql.Fields {
455+
Fields: graphql.FieldsThunk(func() (graphql.Fields, error) {
456456
return graphql.Fields{
457457
"scalar": &graphql.Field{
458458
Type: graphql.Int,
@@ -472,7 +472,7 @@ func init() {
472472
"intBox": &graphql.Field{
473473
Type: intBoxObject,
474474
},
475-
}
475+
}, nil
476476
}),
477477
})
478478
var nonNullStringBox1Interface = graphql.NewInterface(graphql.InterfaceConfig{

validation_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,24 +1388,24 @@ func TestTypeSystem_ObjectsMustAdhereToInterfaceTheyImplement_AcceptsAnObjectWit
13881388
ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {
13891389
return nil
13901390
},
1391-
Fields: (graphql.FieldsThunk)(func() graphql.Fields {
1391+
Fields: (graphql.FieldsThunk)(func() (graphql.Fields, error) {
13921392
return graphql.Fields{
13931393
"field": &graphql.Field{
13941394
Type: anotherInterface,
13951395
},
1396-
}
1396+
}, nil
13971397
}),
13981398
})
13991399
var anotherObject *graphql.Object
14001400
anotherObject = graphql.NewObject(graphql.ObjectConfig{
14011401
Name: "AnotherObject",
14021402
Interfaces: []*graphql.Interface{anotherInterface},
1403-
Fields: (graphql.FieldsThunk)(func() graphql.Fields {
1403+
Fields: (graphql.FieldsThunk)(func() (graphql.Fields, error) {
14041404
return graphql.Fields{
14051405
"field": &graphql.Field{
14061406
Type: anotherObject,
14071407
},
1408-
}
1408+
}, nil
14091409
}),
14101410
})
14111411
_, err := schemaWithFieldType(anotherObject)

0 commit comments

Comments
 (0)