Skip to content

Commit

Permalink
Merge pull request 99designs#45 from dvic/fix-resolver-public-errors
Browse files Browse the repository at this point in the history
Retain orignal resolver error and support overriding error message
  • Loading branch information
vektah authored Mar 22, 2018
2 parents 042dcd9 + 8876aa3 commit 1f37d66
Show file tree
Hide file tree
Showing 12 changed files with 372 additions and 38 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
go get -u github.com/alecthomas/gometalinter github.com/vektah/gorunpkg &&
gometalinter --install &&
dep ensure --vendor-only
- run: go install -v . && go get -u github.com/vektah/dataloaden
- run: go install -v . && go get -u github.com/vektah/dataloaden github.com/pkg/errors
- run: go generate ./... && if [[ $(git --no-pager diff) ]] ; then echo "you need to run go generate" ; git --no-pager diff ; exit 1 ; fi
- run: go vet ./...
- run: go test -race ./...
Expand Down
2 changes: 1 addition & 1 deletion codegen/templates/data.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 26 additions & 6 deletions codegen/templates/generated.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@ import (
{{ end }}
)

func MakeExecutableSchema(resolvers Resolvers) graphql.ExecutableSchema {
return &executableSchema{resolvers}
func MakeExecutableSchema(resolvers Resolvers, opts ...ExecutableOption) graphql.ExecutableSchema {
ret := &executableSchema{resolvers: resolvers}
for _, opt := range opts {
opt(ret)
}
return ret
}

type Resolvers interface {
Expand All @@ -20,8 +24,17 @@ type Resolvers interface {
{{- end }}
}

type ExecutableOption func(*executableSchema)

func WithErrorConverter(fn func(error) string) ExecutableOption {
return func(s *executableSchema) {
s.errorMessageFn = fn
}
}

type executableSchema struct {
resolvers Resolvers
resolvers Resolvers
errorMessageFn func(error) string
}

func (e *executableSchema) Schema() *schema.Schema {
Expand All @@ -30,7 +43,7 @@ func (e *executableSchema) Schema() *schema.Schema {

func (e *executableSchema) Query(ctx context.Context, doc *query.Document, variables map[string]interface{}, op *query.Operation, recover graphql.RecoverFunc) *graphql.Response {
{{- if .QueryRoot }}
ec := executionContext{resolvers: e.resolvers, variables: variables, doc: doc, ctx: ctx, recover: recover}
ec := e.makeExecutionContext(ctx, doc, variables, recover)

data := ec._{{.QueryRoot.GQLType}}(op.Selections)
var buf bytes.Buffer
Expand All @@ -47,7 +60,7 @@ func (e *executableSchema) Query(ctx context.Context, doc *query.Document, varia

func (e *executableSchema) Mutation(ctx context.Context, doc *query.Document, variables map[string]interface{}, op *query.Operation, recover graphql.RecoverFunc) *graphql.Response {
{{- if .MutationRoot }}
ec := executionContext{resolvers: e.resolvers, variables: variables, doc: doc, ctx: ctx, recover: recover}
ec := e.makeExecutionContext(ctx, doc, variables, recover)

data := ec._{{.MutationRoot.GQLType}}(op.Selections)
var buf bytes.Buffer
Expand All @@ -64,7 +77,7 @@ func (e *executableSchema) Mutation(ctx context.Context, doc *query.Document, va

func (e *executableSchema) Subscription(ctx context.Context, doc *query.Document, variables map[string]interface{}, op *query.Operation, recover graphql.RecoverFunc) func() *graphql.Response {
{{- if .SubscriptionRoot }}
ec := executionContext{resolvers: e.resolvers, variables: variables, doc: doc, ctx: ctx, recover: recover}
ec := e.makeExecutionContext(ctx, doc, variables, recover)

next := ec._{{.SubscriptionRoot.GQLType}}(op.Selections)
if ec.Errors != nil {
Expand Down Expand Up @@ -92,6 +105,13 @@ func (e *executableSchema) Subscription(ctx context.Context, doc *query.Document
{{- end }}
}

func (e *executableSchema) makeExecutionContext(ctx context.Context, doc *query.Document, variables map[string]interface{}, recover graphql.RecoverFunc) *executionContext {
errBuilder := errors.Builder{ErrorMessageFn: e.errorMessageFn}
return &executionContext{
Builder: errBuilder, resolvers: e.resolvers, variables: variables, doc: doc, ctx: ctx, recover: recover,
}
}

type executionContext struct {
errors.Builder
resolvers Resolvers
Expand Down
32 changes: 26 additions & 6 deletions example/chat/generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@ import (
schema "github.com/vektah/gqlgen/neelance/schema"
)

func MakeExecutableSchema(resolvers Resolvers) graphql.ExecutableSchema {
return &executableSchema{resolvers}
func MakeExecutableSchema(resolvers Resolvers, opts ...ExecutableOption) graphql.ExecutableSchema {
ret := &executableSchema{resolvers: resolvers}
for _, opt := range opts {
opt(ret)
}
return ret
}

type Resolvers interface {
Expand All @@ -25,16 +29,25 @@ type Resolvers interface {
Subscription_messageAdded(ctx context.Context, roomName string) (<-chan Message, error)
}

type ExecutableOption func(*executableSchema)

func WithErrorConverter(fn func(error) string) ExecutableOption {
return func(s *executableSchema) {
s.errorMessageFn = fn
}
}

type executableSchema struct {
resolvers Resolvers
resolvers Resolvers
errorMessageFn func(error) string
}

func (e *executableSchema) Schema() *schema.Schema {
return parsedSchema
}

func (e *executableSchema) Query(ctx context.Context, doc *query.Document, variables map[string]interface{}, op *query.Operation, recover graphql.RecoverFunc) *graphql.Response {
ec := executionContext{resolvers: e.resolvers, variables: variables, doc: doc, ctx: ctx, recover: recover}
ec := e.makeExecutionContext(ctx, doc, variables, recover)

data := ec._Query(op.Selections)
var buf bytes.Buffer
Expand All @@ -47,7 +60,7 @@ func (e *executableSchema) Query(ctx context.Context, doc *query.Document, varia
}

func (e *executableSchema) Mutation(ctx context.Context, doc *query.Document, variables map[string]interface{}, op *query.Operation, recover graphql.RecoverFunc) *graphql.Response {
ec := executionContext{resolvers: e.resolvers, variables: variables, doc: doc, ctx: ctx, recover: recover}
ec := e.makeExecutionContext(ctx, doc, variables, recover)

data := ec._Mutation(op.Selections)
var buf bytes.Buffer
Expand All @@ -60,7 +73,7 @@ func (e *executableSchema) Mutation(ctx context.Context, doc *query.Document, va
}

func (e *executableSchema) Subscription(ctx context.Context, doc *query.Document, variables map[string]interface{}, op *query.Operation, recover graphql.RecoverFunc) func() *graphql.Response {
ec := executionContext{resolvers: e.resolvers, variables: variables, doc: doc, ctx: ctx, recover: recover}
ec := e.makeExecutionContext(ctx, doc, variables, recover)

next := ec._Subscription(op.Selections)
if ec.Errors != nil {
Expand All @@ -85,6 +98,13 @@ func (e *executableSchema) Subscription(ctx context.Context, doc *query.Document
}
}

func (e *executableSchema) makeExecutionContext(ctx context.Context, doc *query.Document, variables map[string]interface{}, recover graphql.RecoverFunc) *executionContext {
errBuilder := errors.Builder{ErrorMessageFn: e.errorMessageFn}
return &executionContext{
Builder: errBuilder, resolvers: e.resolvers, variables: variables, doc: doc, ctx: ctx, recover: recover,
}
}

type executionContext struct {
errors.Builder
resolvers Resolvers
Expand Down
Loading

0 comments on commit 1f37d66

Please sign in to comment.