Skip to content

Commit 756f374

Browse files
authored
added better error handling for query parsing ⭐ (#126)
* added better error handling for query parsing ⭐ * let the repl continue when the query has syntax errors
1 parent 67437dd commit 756f374

File tree

3 files changed

+41
-8
lines changed

3 files changed

+41
-8
lines changed

sourcecode-parser/antlr/listener_impl.go

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package parser
22

33
import (
4+
"fmt"
45
"strings"
56

67
"github.com/antlr4-go/antlr/v4"
@@ -24,6 +25,15 @@ type SelectList struct {
2425
Alias string
2526
}
2627

28+
type customErrorListener struct {
29+
*antlr.DefaultErrorListener
30+
errors []string
31+
}
32+
33+
func (l *customErrorListener) SyntaxError(_ antlr.Recognizer, _ interface{}, line, column int, msg string, _ antlr.RecognitionException) {
34+
l.errors = append(l.errors, fmt.Sprintf("line %d:%d %s", line, column, msg))
35+
}
36+
2737
func NewCustomQueryListener() *CustomQueryListener {
2838
return &CustomQueryListener{
2939
BaseQueryListener: BaseQueryListener{},
@@ -88,14 +98,28 @@ func (l *CustomQueryListener) ExitAndExpression(ctx *AndExpressionContext) {
8898
}
8999
}
90100

91-
func ParseQuery(inputQuery string) Query {
101+
func ParseQuery(inputQuery string) (Query, error) {
92102
inputStream := antlr.NewInputStream(inputQuery)
93103
lexer := NewQueryLexer(inputStream)
94104
stream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)
95105
p := NewQueryParser(stream)
96106

107+
errorListener := &customErrorListener{}
108+
p.RemoveErrorListeners()
109+
p.AddErrorListener(errorListener)
110+
97111
listener := NewCustomQueryListener()
98-
antlr.ParseTreeWalkerDefault.Walk(listener, p.Query())
112+
tree := p.Query()
113+
114+
if len(errorListener.errors) > 0 {
115+
return Query{}, fmt.Errorf("\n%s", strings.Join(errorListener.errors, "\n"))
116+
}
117+
118+
antlr.ParseTreeWalkerDefault.Walk(listener, tree)
99119

100-
return Query{SelectList: listener.selectList, Expression: listener.expression.String(), Condition: listener.condition}
120+
return Query{
121+
SelectList: listener.selectList,
122+
Expression: listener.expression.String(),
123+
Condition: listener.condition,
124+
}, nil
101125
}

sourcecode-parser/antlr/listener_impl_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,11 @@ func TestParseQuery(t *testing.T) {
6262

6363
for _, tt := range tests {
6464
t.Run(tt.name, func(t *testing.T) {
65-
result := ParseQuery(tt.input)
65+
result, err := ParseQuery(tt.input)
66+
if err != nil {
67+
t.Errorf("ParseQuery() error = %v", err)
68+
return
69+
}
6670
if !reflect.DeepEqual(result, tt.expectedQuery) {
6771
t.Errorf("ParseQuery() = %v, want %v", result, tt.expectedQuery)
6872
}

sourcecode-parser/cmd/query.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,26 +98,31 @@ func executeCLIQuery(project, query, output string, stdin bool) (string, error)
9898
return "Okay, Bye!", nil
9999
}
100100
result, err := processQuery(input, codeGraph, output)
101-
fmt.Println(result)
102101
if err != nil {
103102
analytics.ReportEvent(analytics.ErrorProcessingQuery)
104-
return "", fmt.Errorf("error processing query: %w", err)
103+
err := fmt.Errorf("PathFinder Query syntax error: %w", err)
104+
fmt.Println(err)
105+
} else {
106+
fmt.Println(result)
105107
}
106108
}
107109
} else {
108110
// read from command line
109111
result, err := processQuery(query, codeGraph, output)
110112
if err != nil {
111113
analytics.ReportEvent(analytics.ErrorProcessingQuery)
112-
return "", fmt.Errorf("error processing query: %w", err)
114+
return "", fmt.Errorf("PathFinder Query syntax error: %w", err)
113115
}
114116
return result, nil
115117
}
116118
}
117119

118120
func processQuery(input string, codeGraph *graph.CodeGraph, output string) (string, error) {
119121
fmt.Println("Executing query: " + input)
120-
parsedQuery := parser.ParseQuery(input)
122+
parsedQuery, err := parser.ParseQuery(input)
123+
if err != nil {
124+
return "", err
125+
}
121126
// split the input string if WHERE
122127
parsedQuery.Expression = strings.Split(input, "WHERE")[1]
123128
entities := graph.QueryEntities(codeGraph, parsedQuery)

0 commit comments

Comments
 (0)