-
Notifications
You must be signed in to change notification settings - Fork 494
Add Custom Directive Support for Fields #543
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
5e217c2
fd885f0
da343da
64aa7b9
748ce7a
0bd7a07
ddc1b7a
cf821db
77530e9
483881c
54416fd
870991a
945f124
92a4068
a1157fa
3b84a57
9d127ce
b290e8b
2af43e4
12642b1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -25,6 +25,7 @@ type Request struct { | |||||
Logger log.Logger | ||||||
PanicHandler errors.PanicHandler | ||||||
SubscribeResolverTimeout time.Duration | ||||||
Visitors map[string]types.DirectiveVisitor | ||||||
} | ||||||
|
||||||
func (r *Request) handlePanic(ctx context.Context) { | ||||||
|
@@ -208,8 +209,48 @@ func execFieldSelection(ctx context.Context, r *Request, s *resolvable.Schema, f | |||||
if f.field.ArgsPacker != nil { | ||||||
in = append(in, f.field.PackedArgs) | ||||||
} | ||||||
|
||||||
// Before hook directive visitor | ||||||
if len(f.field.Directives) > 0 { | ||||||
for _, directive := range f.field.Directives { | ||||||
if visitor, ok := r.Visitors[directive.Name.Name]; ok { | ||||||
values := make([]interface{}, 0, len(in)) | ||||||
for _, inValue := range in { | ||||||
values = append(values, inValue.Interface()) | ||||||
} | ||||||
|
||||||
visitorErr := visitor.Before(ctx, directive, values) | ||||||
if visitorErr != nil { | ||||||
err := errors.Errorf("%s", visitorErr) | ||||||
err.Path = path.toSlice() | ||||||
err.ResolverError = visitorErr | ||||||
return err | ||||||
} | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
// Call method | ||||||
callOut := res.Method(f.field.MethodIndex).Call(in) | ||||||
result = callOut[0] | ||||||
|
||||||
// After hook directive visitor (when no error is returned from resolver) | ||||||
if !f.field.HasError && len(f.field.Directives) > 0 { | ||||||
for _, directive := range f.field.Directives { | ||||||
if visitor, ok := r.Visitors[directive.Name.Name]; ok { | ||||||
returned, visitorErr := visitor.After(ctx, directive, result.Interface()) | ||||||
if visitorErr != nil { | ||||||
err := errors.Errorf("%s", visitorErr) | ||||||
err.Path = path.toSlice() | ||||||
err.ResolverError = visitorErr | ||||||
return err | ||||||
} else { | ||||||
result = reflect.ValueOf(returned) | ||||||
} | ||||||
rudle marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
if f.field.HasError && !callOut[1].IsNil() { | ||||||
resolverErr := callOut[1].Interface().(error) | ||||||
err := errors.Errorf("%s", resolverErr) | ||||||
|
@@ -225,7 +266,38 @@ func execFieldSelection(ctx context.Context, r *Request, s *resolvable.Schema, f | |||||
if res.Kind() == reflect.Ptr { | ||||||
res = res.Elem() | ||||||
} | ||||||
// Before hook directive visitor struct field | ||||||
if len(f.field.Directives) > 0 { | ||||||
for _, directive := range f.field.Directives { | ||||||
if visitor, ok := r.Visitors[directive.Name.Name]; ok { | ||||||
// TODO check that directive arity == 0-that should be an error at schema init time | ||||||
visitorErr := visitor.Before(ctx, directive, nil) | ||||||
if visitorErr != nil { | ||||||
err := errors.Errorf("%s", visitorErr) | ||||||
err.Path = path.toSlice() | ||||||
err.ResolverError = visitorErr | ||||||
return err | ||||||
} | ||||||
} | ||||||
} | ||||||
} | ||||||
result = res.FieldByIndex(f.field.FieldIndex) | ||||||
// After hook directive visitor (when no error is returned from resolver) | ||||||
if !f.field.HasError && len(f.field.Directives) > 0 { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think that struct resolver fields can ever produce an error but I'm not an expert. Shall we delete this, Pavel?
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, struct fields cannot produce an error. It doesn't make sense to me to check for one. |
||||||
for _, directive := range f.field.Directives { | ||||||
if visitor, ok := r.Visitors[directive.Name.Name]; ok { | ||||||
returned, visitorErr := visitor.After(ctx, directive, result.Interface()) | ||||||
if visitorErr != nil { | ||||||
err := errors.Errorf("%s", visitorErr) | ||||||
err.Path = path.toSlice() | ||||||
err.ResolverError = visitorErr | ||||||
return err | ||||||
} else { | ||||||
result = reflect.ValueOf(returned) | ||||||
} | ||||||
rudle marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
} | ||||||
} | ||||||
} | ||||||
} | ||||||
return nil | ||||||
}() | ||||||
|
Uh oh!
There was an error while loading. Please reload this page.