Skip to content

Commit 9462bf9

Browse files
committed
[devtools] [repl] Do not print character number of error
The character number reported by Yaegi (where the error occurred) is always wrong. It will be better to simply hide this information from the user.
1 parent b124302 commit 9462bf9

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

devtools/internal/interpreter/interpreter.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ func (i Instance) runGoCode(source string) (r EvalResult, e error) {
225225
err := recover()
226226
if err != nil {
227227
r = GoCodeExecuted
228-
e = fmt.Errorf("panic when running Yaegi: %s", err)
228+
e = fmt.Errorf("panic when running Yaegi Go interpreter: %s", err)
229229
}
230230
}()
231231

@@ -244,14 +244,37 @@ func (i Instance) runGoCode(source string) (r EvalResult, e error) {
244244
return Continued, nil
245245
}
246246

247-
return GoCodeExecuted, err
247+
return GoCodeExecuted, convertYaegiError(err)
248248
}
249249

250250
printResult(res)
251251

252252
return GoCodeExecuted, nil
253253
}
254254

255+
var (
256+
yaegiCfgErrorPattern = regexp.MustCompile(`^(\d+:)(\d+:)(.*)`) // control flow graph generation error
257+
yaegiScannerErrorPattern = regexp.MustCompile(`^_\.go:(\d+:)(\d+:)(.*)`)
258+
)
259+
260+
// Yaegi reports wrong character number in error messages. It is better to remove this information completely.
261+
func convertYaegiError(err error) error {
262+
errStr := err.Error()
263+
264+
switch {
265+
case yaegiCfgErrorPattern.MatchString(errStr):
266+
return fmt.Errorf(
267+
yaegiCfgErrorPattern.ReplaceAllString(errStr, "$1$3"),
268+
)
269+
case yaegiScannerErrorPattern.MatchString(errStr):
270+
return fmt.Errorf(
271+
yaegiScannerErrorPattern.ReplaceAllString(errStr, "$1$3"),
272+
)
273+
default:
274+
return err
275+
}
276+
}
277+
255278
// shouldContinueOnError returns true if the error can be safely ignored
256279
// to let the caller grab one more line before retrying to parse its input.
257280
func shouldContinueOnError(err error, source string) bool {

devtools/internal/interpreter/interpreter_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,37 @@ func TestEval(t *testing.T) {
249249
require.NoError(t, err)
250250
assert.Equal(t, "interpreter_test.anotherType: {}\n", swapper.ReadOutput(t))
251251
})
252+
253+
t.Run("should convert error message to exclude invalid character number", func(t *testing.T) {
254+
tests := map[string]struct {
255+
source string
256+
expectedErrMessage string
257+
}{
258+
"undefined": {
259+
source: "undefinedVar",
260+
expectedErrMessage: "1: undefined: undefinedVar",
261+
},
262+
"undefined in second line": {
263+
source: "{ \n undefinedVar \n }",
264+
expectedErrMessage: "2: undefined: undefinedVar",
265+
},
266+
"invalid number literal": {
267+
source: "a := 123a123",
268+
expectedErrMessage: "1: expected ';', found a123 (and 1 more errors)",
269+
},
270+
"invalid number literal in second line": {
271+
source: "{ \n a := 123a123 \n }",
272+
expectedErrMessage: "2: expected ';', found a123 (and 1 more errors)",
273+
},
274+
}
275+
for name, testCase := range tests {
276+
t.Run(name, func(t *testing.T) {
277+
_, err := newInterpreterInstance(t).Eval(testCase.source)
278+
require.Error(t, err)
279+
assert.Equal(t, testCase.expectedErrMessage, err.Error())
280+
})
281+
}
282+
})
252283
}
253284

254285
func TestExport(t *testing.T) {

0 commit comments

Comments
 (0)