From f1bc9b21f69b8e66144c2fe78faf52ea4e677a7b Mon Sep 17 00:00:00 2001 From: Richard Musiol Date: Thu, 20 Oct 2016 12:50:28 +0200 Subject: [PATCH] syntax errors with proper line and column --- errors/errors.go | 4 ++-- internal/lexer/lexer.go | 21 +++++++++++++++++++-- internal/query/query.go | 18 ++++++------------ internal/schema/schema.go | 20 ++++++++------------ 4 files changed, 35 insertions(+), 28 deletions(-) diff --git a/errors/errors.go b/errors/errors.go index 6824cb35705..437d3fa5a94 100644 --- a/errors/errors.go +++ b/errors/errors.go @@ -14,13 +14,13 @@ type Location struct { func Errorf(format string, a ...interface{}) *GraphQLError { return &GraphQLError{ - Message: fmt.Sprintf(format, a), + Message: fmt.Sprintf(format, a...), } } func ErrorfWithLoc(line int, column int, format string, a ...interface{}) *GraphQLError { return &GraphQLError{ - Message: fmt.Sprintf(format, a), + Message: fmt.Sprintf(format, a...), Locations: []*Location{{ Line: line, Column: column, diff --git a/internal/lexer/lexer.go b/internal/lexer/lexer.go index fb0348b32e8..7cc9cd1d44e 100644 --- a/internal/lexer/lexer.go +++ b/internal/lexer/lexer.go @@ -4,9 +4,11 @@ import ( "fmt" "strconv" "text/scanner" + + "github.com/neelance/graphql-go/errors" ) -type SyntaxError string +type syntaxError string type Lexer struct { sc *scanner.Scanner @@ -19,6 +21,21 @@ func New(sc *scanner.Scanner) *Lexer { return l } +func (l *Lexer) CatchSyntaxError(f func()) (errRes *errors.GraphQLError) { + defer func() { + if err := recover(); err != nil { + if err, ok := err.(syntaxError); ok { + errRes = errors.ErrorfWithLoc(l.sc.Line, l.sc.Column, "syntax error: %s", err) + return + } + panic(err) + } + }() + + f() + return +} + func (l *Lexer) Peek() rune { return l.next } @@ -72,5 +89,5 @@ func (l *Lexer) ConsumeToken(expected rune) { } func (l *Lexer) SyntaxError(message string) { - panic(SyntaxError(fmt.Sprintf("%s:%d: syntax error: %s", l.sc.Filename, l.sc.Line, message))) + panic(syntaxError(message)) } diff --git a/internal/query/query.go b/internal/query/query.go index fe1e3f7d690..b14991cbbc4 100644 --- a/internal/query/query.go +++ b/internal/query/query.go @@ -93,23 +93,17 @@ type Literal struct { func (Variable) isValue() {} func (Literal) isValue() {} -func Parse(queryString string) (res *Document, errRes *errors.GraphQLError) { +func Parse(queryString string) (doc *Document, err *errors.GraphQLError) { sc := &scanner.Scanner{ Mode: scanner.ScanIdents | scanner.ScanFloats | scanner.ScanStrings, } sc.Init(strings.NewReader(queryString)) - defer func() { - if err := recover(); err != nil { - if err, ok := err.(lexer.SyntaxError); ok { - errRes = errors.Errorf("%s", string(err)) - return - } - panic(err) - } - }() - - return parseDocument(lexer.New(sc)), nil + l := lexer.New(sc) + err = l.CatchSyntaxError(func() { + doc = parseDocument(l) + }) + return } func parseDocument(l *lexer.Lexer) *Document { diff --git a/internal/schema/schema.go b/internal/schema/schema.go index 6b43842d0fb..f07900c0087 100644 --- a/internal/schema/schema.go +++ b/internal/schema/schema.go @@ -80,23 +80,19 @@ type Parameter struct { Default string } -func Parse(schemaString string) (res *Schema, errRes *errors.GraphQLError) { +func Parse(schemaString string) (s *Schema, err *errors.GraphQLError) { sc := &scanner.Scanner{ Mode: scanner.ScanIdents | scanner.ScanFloats | scanner.ScanStrings, } sc.Init(strings.NewReader(schemaString)) - defer func() { - if err := recover(); err != nil { - if err, ok := err.(lexer.SyntaxError); ok { - errRes = errors.Errorf("%s", string(err)) - return - } - panic(err) - } - }() - - s := parseSchema(lexer.New(sc)) + l := lexer.New(sc) + err = l.CatchSyntaxError(func() { + s = parseSchema(l) + }) + if err != nil { + return nil, err + } for _, obj := range s.Objects { if obj.Implements != "" {