[release/1.4.6] console, internal/jsre: colorize JavaScript exceptions too

(cherry picked from commit 14ae5708d6)
pull/2663/head
Péter Szilágyi 9 years ago
parent c39de61a0a
commit 7c90a2e42e
  1. 15
      console/console.go
  2. 12
      console/console_test.go
  3. 4
      internal/jsre/jsre.go
  4. 18
      internal/jsre/pretty.go

@ -182,7 +182,11 @@ func (c *Console) init(preload []string) error {
// Preload any JavaScript files before starting the console // Preload any JavaScript files before starting the console
for _, path := range preload { for _, path := range preload {
if err := c.jsre.Exec(path); err != nil { if err := c.jsre.Exec(path); err != nil {
return fmt.Errorf("%s: %v", path, jsErrorString(err)) failure := err.Error()
if ottoErr, ok := err.(*otto.Error); ok {
failure = ottoErr.String()
}
return fmt.Errorf("%s: %v", path, failure)
} }
} }
// Configure the console's input prompter for scrollback and tab completion // Configure the console's input prompter for scrollback and tab completion
@ -269,7 +273,6 @@ func (c *Console) Evaluate(statement string) error {
} }
}() }()
if err := c.jsre.Evaluate(statement, c.printer); err != nil { if err := c.jsre.Evaluate(statement, c.printer); err != nil {
fmt.Fprintf(c.printer, "%v\n", jsErrorString(err))
return err return err
} }
return nil return nil
@ -359,11 +362,3 @@ func (c *Console) Stop(graceful bool) error {
c.jsre.Stop(graceful) c.jsre.Stop(graceful)
return nil return nil
} }
// jsErrorString adds a backtrace to errors generated by otto.
func jsErrorString(err error) string {
if ottoErr, ok := err.(*otto.Error); ok {
return ottoErr.String()
}
return err.Error()
}

@ -281,3 +281,15 @@ func TestPrettyPrint(t *testing.T) {
t.Fatalf("pretty print mismatch: have %s, want %s", output, want) t.Fatalf("pretty print mismatch: have %s, want %s", output, want)
} }
} }
// Tests that the JavaScript exceptions are properly formatted and colored.
func TestPrettyError(t *testing.T) {
tester := newTester(t, nil)
defer tester.Close(t)
tester.console.Evaluate("throw 'hello'")
want := jsre.ErrorColor("hello") + "\n"
if output := string(tester.output.Bytes()); output != want {
t.Fatalf("pretty error mismatch: have %s, want %s", output, want)
}
}

@ -303,11 +303,11 @@ func (self *JSRE) Evaluate(code string, w io.Writer) error {
self.Do(func(vm *otto.Otto) { self.Do(func(vm *otto.Otto) {
val, err := vm.Run(code) val, err := vm.Run(code)
if err != nil { if err != nil {
fail = err prettyError(vm, err, w)
} else { } else {
prettyPrint(vm, val, w) prettyPrint(vm, val, w)
fmt.Fprintln(w)
} }
fmt.Fprintln(w)
}) })
return fail return fail
} }

@ -37,6 +37,7 @@ var (
SpecialColor = color.New(color.Bold).SprintfFunc() SpecialColor = color.New(color.Bold).SprintfFunc()
NumberColor = color.New(color.FgRed).SprintfFunc() NumberColor = color.New(color.FgRed).SprintfFunc()
StringColor = color.New(color.FgGreen).SprintfFunc() StringColor = color.New(color.FgGreen).SprintfFunc()
ErrorColor = color.New(color.FgHiRed).SprintfFunc()
) )
// these fields are hidden when printing objects. // these fields are hidden when printing objects.
@ -55,6 +56,23 @@ func prettyPrint(vm *otto.Otto, value otto.Value, w io.Writer) {
ppctx{vm: vm, w: w}.printValue(value, 0, false) ppctx{vm: vm, w: w}.printValue(value, 0, false)
} }
// prettyError writes err to standard output.
func prettyError(vm *otto.Otto, err error, w io.Writer) {
failure := err.Error()
if ottoErr, ok := err.(*otto.Error); ok {
failure = ottoErr.String()
}
fmt.Fprint(w, ErrorColor("%s", failure))
}
// jsErrorString adds a backtrace to errors generated by otto.
func jsErrorString(err error) string {
if ottoErr, ok := err.(*otto.Error); ok {
return ottoErr.String()
}
return err.Error()
}
func prettyPrintJS(call otto.FunctionCall, w io.Writer) otto.Value { func prettyPrintJS(call otto.FunctionCall, w io.Writer) otto.Value {
for _, v := range call.ArgumentList { for _, v := range call.ArgumentList {
prettyPrint(call.Otto, v, w) prettyPrint(call.Otto, v, w)

Loading…
Cancel
Save