Răsfoiți Sursa

Merge pull request #2478 from fjl/geth-js-tweak

cmd/geth, jsre: improve the js command
Felix Lange 9 ani în urmă
părinte
comite
3d6d828caf
3 a modificat fișierele cu 34 adăugiri și 13 ștergeri
  1. 7 9
      cmd/geth/js.go
  2. 19 3
      cmd/geth/main.go
  3. 8 1
      jsre/jsre.go

+ 7 - 9
cmd/geth/js.go

@@ -123,7 +123,7 @@ func (self *jsre) batch(statement string) {
 	err := self.re.EvalAndPrettyPrint(statement)
 
 	if err != nil {
-		fmt.Printf("error: %v", err)
+		fmt.Printf("%v", jsErrorString(err))
 	}
 
 	if self.atexit != nil {
@@ -301,21 +301,19 @@ func (self *jsre) preloadJSFiles(ctx *cli.Context) error {
 		for _, file := range jsFiles {
 			filename := common.AbsolutePath(assetPath, strings.TrimSpace(file))
 			if err := self.re.Exec(filename); err != nil {
-				return fmt.Errorf("%s: %v", file, err)
+				return fmt.Errorf("%s: %v", file, jsErrorString(err))
 			}
 		}
 	}
 	return nil
 }
 
-// exec executes the JS file with the given filename and stops the JSRE
-func (self *jsre) exec(filename string) error {
-	if err := self.re.Exec(filename); err != nil {
-		self.re.Stop(false)
-		return fmt.Errorf("Javascript Error: %v", err)
+// jsErrorString adds a backtrace to errors generated by otto.
+func jsErrorString(err error) string {
+	if ottoErr, ok := err.(*otto.Error); ok {
+		return ottoErr.String()
 	}
-	self.re.Stop(true)
-	return nil
+	return err.Error()
 }
 
 func (self *jsre) interactive() {

+ 19 - 3
cmd/geth/main.go

@@ -21,6 +21,7 @@ import (
 	"fmt"
 	"io/ioutil"
 	"os"
+	"os/signal"
 	"path/filepath"
 	"runtime"
 	"strconv"
@@ -353,7 +354,7 @@ func console(ctx *cli.Context) {
 	// preload user defined JS files into the console
 	err = repl.preloadJSFiles(ctx)
 	if err != nil {
-		utils.Fatalf("unable to preload JS file %v", err)
+		utils.Fatalf("%v", err)
 	}
 
 	// in case the exec flag holds a JS statement execute it and return
@@ -372,6 +373,7 @@ func execScripts(ctx *cli.Context) {
 	// Create and start the node based on the CLI flags
 	node := utils.MakeSystemNode(ClientIdentifier, nodeNameVersion, makeDefaultExtra(), ctx)
 	startNode(ctx, node)
+	defer node.Stop()
 
 	// Attach to the newly started node and execute the given scripts
 	client, err := node.Attach()
@@ -383,10 +385,24 @@ func execScripts(ctx *cli.Context) {
 		ctx.GlobalString(utils.RPCCORSDomainFlag.Name),
 		client, false)
 
+	// Run all given files.
 	for _, file := range ctx.Args() {
-		repl.exec(file)
+		if err = repl.re.Exec(file); err != nil {
+			break
+		}
 	}
-	node.Stop()
+	if err != nil {
+		utils.Fatalf("JavaScript Error: %v", jsErrorString(err))
+	}
+	// JS files loaded successfully.
+	// Wait for pending callbacks, but stop for Ctrl-C.
+	abort := make(chan os.Signal, 1)
+	signal.Notify(abort, os.Interrupt)
+	go func() {
+		<-abort
+		repl.re.Stop(false)
+	}()
+	repl.re.Stop(true)
 }
 
 // startNode boots up the system node and all registered protocols, after which

+ 8 - 1
jsre/jsre.go

@@ -235,7 +235,14 @@ func (self *JSRE) Exec(file string) error {
 	if err != nil {
 		return err
 	}
-	self.Do(func(vm *otto.Otto) { _, err = vm.Run(code) })
+	var script *otto.Script
+	self.Do(func(vm *otto.Otto) {
+		script, err = vm.Compile(file, code)
+		if err != nil {
+			return
+		}
+		_, err = vm.Run(script)
+	})
 	return err
 }