diff --git a/graphql/executor/executor.go b/graphql/executor/executor.go index c0f0721c151..6168f987056 100644 --- a/graphql/executor/executor.go +++ b/graphql/executor/executor.go @@ -7,6 +7,7 @@ import ( "github.com/vektah/gqlparser/v2/gqlerror" "github.com/vektah/gqlparser/v2/parser" "github.com/vektah/gqlparser/v2/validator" + "github.com/vektah/gqlparser/v2/validator/rules" "github.com/99designs/gqlgen/graphql" "github.com/99designs/gqlgen/graphql/errcode" @@ -24,7 +25,8 @@ type Executor struct { recoverFunc graphql.RecoverFunc queryCache graphql.Cache[*ast.QueryDocument] - parserTokenLimit int + parserTokenLimit int + disableSuggestion bool } var _ graphql.GraphExecutor = &Executor{} @@ -177,6 +179,10 @@ func (e *Executor) SetParserTokenLimit(limit int) { e.parserTokenLimit = limit } +func (e *Executor) SetDisableSuggestion(value bool) { + e.disableSuggestion = value +} + // parseQuery decodes the incoming query and validates it, pulling from cache if present. // // NOTE: This should NOT look at variables, they will change per request. It should only parse and @@ -216,6 +222,14 @@ func (e *Executor) parseQuery( return nil, gqlerror.List{gqlErr} } + // swap out the FieldsOnCorrectType rule with one that doesn't provide suggestions + if e.disableSuggestion { + validator.RemoveRule("FieldsOnCorrectType") + + rule := rules.FieldsOnCorrectTypeRuleWithoutSuggestions + validator.AddRule(rule.Name, rule.RuleFunc) + } + listErr := validator.Validate(e.es.Schema(), doc) if len(listErr) != 0 { for _, e := range listErr { diff --git a/graphql/executor/executor_test.go b/graphql/executor/executor_test.go index b8e87852aa0..d5e49522f02 100644 --- a/graphql/executor/executor_test.go +++ b/graphql/executor/executor_test.go @@ -169,6 +169,22 @@ func TestExecutor(t *testing.T) { }) } +func TestExecutorDisableSuggestion(t *testing.T) { + exec := testexecutor.New() + t.Run("by default, the error message will include suggestions", func(t *testing.T) { + resp := query(exec, "", "{nam}") + assert.Equal(t, "", string(resp.Data)) + assert.Equal(t, "input:1: Cannot query field \"nam\" on type \"Query\". Did you mean \"name\"?\n", resp.Errors.Error()) + }) + + t.Run("disable suggestion, the error message will not include suggestions", func(t *testing.T) { + exec.SetDisableSuggestion(true) + resp := query(exec, "", "{nam}") + assert.Equal(t, "", string(resp.Data)) + assert.Equal(t, "input:1: Cannot query field \"nam\" on type \"Query\".\n", resp.Errors.Error()) + }) +} + type testParamMutator struct { Mutate func(context.Context, *graphql.RawParams) *gqlerror.Error } diff --git a/graphql/handler/server.go b/graphql/handler/server.go index f186bb49ade..d80e60dc9cf 100644 --- a/graphql/handler/server.go +++ b/graphql/handler/server.go @@ -87,6 +87,10 @@ func (s *Server) SetParserTokenLimit(limit int) { s.exec.SetParserTokenLimit(limit) } +func (s *Server) SetDisableSuggestion(value bool) { + s.exec.SetDisableSuggestion(value) +} + func (s *Server) Use(extension graphql.HandlerExtension) { s.exec.Use(extension) }