Browse Source

etcdctl/ctlv2: error handling with JSON

Gyu-Ho Lee 9 years ago
parent
commit
9b470ef4c0

+ 2 - 2
etcdctl/ctlv2/command/cluster_health.go

@@ -54,7 +54,7 @@ func handleClusterHealth(c *cli.Context) error {
 
 	tr, err := getTransport(c)
 	if err != nil {
-		handleError(ExitServerError, err)
+		handleError(c, ExitServerError, err)
 	}
 
 	hc := http.Client{
@@ -66,7 +66,7 @@ func handleClusterHealth(c *cli.Context) error {
 	ms, err := mi.List(context.TODO())
 	if err != nil {
 		fmt.Println("cluster may be unhealthy: failed to list members")
-		handleError(ExitServerError, err)
+		handleError(c, ExitServerError, err)
 	}
 
 	for {

+ 14 - 1
etcdctl/ctlv2/command/error.go

@@ -15,10 +15,12 @@
 package command
 
 import (
+	"encoding/json"
 	"fmt"
 	"os"
 
 	"github.com/coreos/etcd/client"
+	"github.com/urfave/cli"
 )
 
 const (
@@ -30,7 +32,18 @@ const (
 	ExitClusterNotHealthy
 )
 
-func handleError(code int, err error) {
+func handleError(c *cli.Context, code int, err error) {
+	if c.GlobalString("output") == "json" {
+		if err, ok := err.(*client.Error); ok {
+			b, err := json.Marshal(err)
+			if err != nil {
+				panic(err)
+			}
+			fmt.Fprintln(os.Stderr, string(b))
+			os.Exit(code)
+		}
+	}
+
 	fmt.Fprintln(os.Stderr, "Error: ", err)
 	if cerr, ok := err.(*client.ClusterError); ok {
 		fmt.Fprintln(os.Stderr, cerr.Detail())

+ 2 - 2
etcdctl/ctlv2/command/exec_watch_command.go

@@ -49,7 +49,7 @@ func execWatchCommandFunc(c *cli.Context, ki client.KeysAPI) {
 	argslen := len(args)
 
 	if argslen < 2 {
-		handleError(ExitBadArgs, errors.New("key and command to exec required"))
+		handleError(c, ExitBadArgs, errors.New("key and command to exec required"))
 	}
 
 	var (
@@ -95,7 +95,7 @@ func execWatchCommandFunc(c *cli.Context, ki client.KeysAPI) {
 	for {
 		resp, err := w.Next(context.TODO())
 		if err != nil {
-			handleError(ExitServerError, err)
+			handleError(c, ExitServerError, err)
 		}
 		if resp.Node.Dir {
 			fmt.Fprintf(os.Stderr, "Ignored dir %s change\n", resp.Node.Key)

+ 2 - 2
etcdctl/ctlv2/command/get_command.go

@@ -43,7 +43,7 @@ func NewGetCommand() cli.Command {
 // getCommandFunc executes the "get" command.
 func getCommandFunc(c *cli.Context, ki client.KeysAPI) {
 	if len(c.Args()) == 0 {
-		handleError(ExitBadArgs, errors.New("key required"))
+		handleError(c, ExitBadArgs, errors.New("key required"))
 	}
 
 	key := c.Args()[0]
@@ -54,7 +54,7 @@ func getCommandFunc(c *cli.Context, ki client.KeysAPI) {
 	resp, err := ki.Get(ctx, key, &client.GetOptions{Sort: sorted, Quorum: quorum})
 	cancel()
 	if err != nil {
-		handleError(ExitServerError, err)
+		handleError(c, ExitServerError, err)
 	}
 
 	if resp.Node.Dir {

+ 1 - 1
etcdctl/ctlv2/command/ls_command.go

@@ -54,7 +54,7 @@ func lsCommandFunc(c *cli.Context, ki client.KeysAPI) {
 	resp, err := ki.Get(ctx, key, &client.GetOptions{Sort: sort, Recursive: recursive, Quorum: quorum})
 	cancel()
 	if err != nil {
-		handleError(ExitServerError, err)
+		handleError(c, ExitServerError, err)
 	}
 
 	printLs(c, resp)

+ 3 - 3
etcdctl/ctlv2/command/mk_command.go

@@ -43,12 +43,12 @@ func NewMakeCommand() cli.Command {
 // mkCommandFunc executes the "mk" command.
 func mkCommandFunc(c *cli.Context, ki client.KeysAPI) {
 	if len(c.Args()) == 0 {
-		handleError(ExitBadArgs, errors.New("key required"))
+		handleError(c, ExitBadArgs, errors.New("key required"))
 	}
 	key := c.Args()[0]
 	value, err := argOrStdin(c.Args(), os.Stdin, 1)
 	if err != nil {
-		handleError(ExitBadArgs, errors.New("value required"))
+		handleError(c, ExitBadArgs, errors.New("value required"))
 	}
 
 	ttl := c.Int("ttl")
@@ -69,7 +69,7 @@ func mkCommandFunc(c *cli.Context, ki client.KeysAPI) {
 	}
 	cancel()
 	if err != nil {
-		handleError(ExitServerError, err)
+		handleError(c, ExitServerError, err)
 	}
 
 	printResponseKey(resp, c.GlobalString("output"))

+ 2 - 2
etcdctl/ctlv2/command/mkdir_command.go

@@ -41,7 +41,7 @@ func NewMakeDirCommand() cli.Command {
 // mkdirCommandFunc executes the "mkdir" command.
 func mkdirCommandFunc(c *cli.Context, ki client.KeysAPI, prevExist client.PrevExistType) {
 	if len(c.Args()) == 0 {
-		handleError(ExitBadArgs, errors.New("key required"))
+		handleError(c, ExitBadArgs, errors.New("key required"))
 	}
 
 	key := c.Args()[0]
@@ -51,7 +51,7 @@ func mkdirCommandFunc(c *cli.Context, ki client.KeysAPI, prevExist client.PrevEx
 	resp, err := ki.Set(ctx, key, "", &client.SetOptions{TTL: time.Duration(ttl) * time.Second, Dir: true, PrevExist: prevExist})
 	cancel()
 	if err != nil {
-		handleError(ExitServerError, err)
+		handleError(c, ExitServerError, err)
 	}
 	if c.GlobalString("output") != "simple" {
 		printResponseKey(resp, c.GlobalString("output"))

+ 2 - 2
etcdctl/ctlv2/command/rm_command.go

@@ -43,7 +43,7 @@ func NewRemoveCommand() cli.Command {
 // rmCommandFunc executes the "rm" command.
 func rmCommandFunc(c *cli.Context, ki client.KeysAPI) {
 	if len(c.Args()) == 0 {
-		handleError(ExitBadArgs, errors.New("key required"))
+		handleError(c, ExitBadArgs, errors.New("key required"))
 	}
 	key := c.Args()[0]
 	recursive := c.Bool("recursive")
@@ -55,7 +55,7 @@ func rmCommandFunc(c *cli.Context, ki client.KeysAPI) {
 	resp, err := ki.Delete(ctx, key, &client.DeleteOptions{PrevIndex: uint64(prevIndex), PrevValue: prevValue, Dir: dir, Recursive: recursive})
 	cancel()
 	if err != nil {
-		handleError(ExitServerError, err)
+		handleError(c, ExitServerError, err)
 	}
 	if !resp.Node.Dir || c.GlobalString("output") != "simple" {
 		printResponseKey(resp, c.GlobalString("output"))

+ 2 - 2
etcdctl/ctlv2/command/rmdir_command.go

@@ -37,7 +37,7 @@ func NewRemoveDirCommand() cli.Command {
 // rmdirCommandFunc executes the "rmdir" command.
 func rmdirCommandFunc(c *cli.Context, ki client.KeysAPI) {
 	if len(c.Args()) == 0 {
-		handleError(ExitBadArgs, errors.New("key required"))
+		handleError(c, ExitBadArgs, errors.New("key required"))
 	}
 	key := c.Args()[0]
 
@@ -45,7 +45,7 @@ func rmdirCommandFunc(c *cli.Context, ki client.KeysAPI) {
 	resp, err := ki.Delete(ctx, key, &client.DeleteOptions{Dir: true})
 	cancel()
 	if err != nil {
-		handleError(ExitServerError, err)
+		handleError(c, ExitServerError, err)
 	}
 
 	if !resp.Node.Dir || c.GlobalString("output") != "simple" {

+ 3 - 3
etcdctl/ctlv2/command/set_command.go

@@ -50,12 +50,12 @@ func NewSetCommand() cli.Command {
 // setCommandFunc executes the "set" command.
 func setCommandFunc(c *cli.Context, ki client.KeysAPI) {
 	if len(c.Args()) == 0 {
-		handleError(ExitBadArgs, errors.New("key required"))
+		handleError(c, ExitBadArgs, errors.New("key required"))
 	}
 	key := c.Args()[0]
 	value, err := argOrStdin(c.Args(), os.Stdin, 1)
 	if err != nil {
-		handleError(ExitBadArgs, errors.New("value required"))
+		handleError(c, ExitBadArgs, errors.New("value required"))
 	}
 
 	ttl := c.Int("ttl")
@@ -66,7 +66,7 @@ func setCommandFunc(c *cli.Context, ki client.KeysAPI) {
 	resp, err := ki.Set(ctx, key, value, &client.SetOptions{TTL: time.Duration(ttl) * time.Second, PrevIndex: uint64(prevIndex), PrevValue: prevValue})
 	cancel()
 	if err != nil {
-		handleError(ExitServerError, err)
+		handleError(c, ExitServerError, err)
 	}
 
 	printResponseKey(resp, c.GlobalString("output"))

+ 3 - 3
etcdctl/ctlv2/command/update_command.go

@@ -42,12 +42,12 @@ func NewUpdateCommand() cli.Command {
 // updateCommandFunc executes the "update" command.
 func updateCommandFunc(c *cli.Context, ki client.KeysAPI) {
 	if len(c.Args()) == 0 {
-		handleError(ExitBadArgs, errors.New("key required"))
+		handleError(c, ExitBadArgs, errors.New("key required"))
 	}
 	key := c.Args()[0]
 	value, err := argOrStdin(c.Args(), os.Stdin, 1)
 	if err != nil {
-		handleError(ExitBadArgs, errors.New("value required"))
+		handleError(c, ExitBadArgs, errors.New("value required"))
 	}
 
 	ttl := c.Int("ttl")
@@ -56,7 +56,7 @@ func updateCommandFunc(c *cli.Context, ki client.KeysAPI) {
 	resp, err := ki.Set(ctx, key, value, &client.SetOptions{TTL: time.Duration(ttl) * time.Second, PrevExist: client.PrevExist})
 	cancel()
 	if err != nil {
-		handleError(ExitServerError, err)
+		handleError(c, ExitServerError, err)
 	}
 
 	printResponseKey(resp, c.GlobalString("output"))

+ 2 - 2
etcdctl/ctlv2/command/update_dir_command.go

@@ -41,7 +41,7 @@ func NewUpdateDirCommand() cli.Command {
 // updatedirCommandFunc executes the "updatedir" command.
 func updatedirCommandFunc(c *cli.Context, ki client.KeysAPI) {
 	if len(c.Args()) == 0 {
-		handleError(ExitBadArgs, errors.New("key required"))
+		handleError(c, ExitBadArgs, errors.New("key required"))
 	}
 	key := c.Args()[0]
 	ttl := c.Int("ttl")
@@ -49,7 +49,7 @@ func updatedirCommandFunc(c *cli.Context, ki client.KeysAPI) {
 	resp, err := ki.Set(ctx, key, "", &client.SetOptions{TTL: time.Duration(ttl) * time.Second, Dir: true, PrevExist: client.PrevExist})
 	cancel()
 	if err != nil {
-		handleError(ExitServerError, err)
+		handleError(c, ExitServerError, err)
 	}
 	if c.GlobalString("output") != "simple" {
 		printResponseKey(resp, c.GlobalString("output"))

+ 2 - 2
etcdctl/ctlv2/command/util.go

@@ -237,10 +237,10 @@ func mustNewClient(c *cli.Context) client.Client {
 			if err == client.ErrNoEndpoints {
 				fmt.Fprintf(os.Stderr, "etcd cluster has no published client endpoints.\n")
 				fmt.Fprintf(os.Stderr, "Try '--no-sync' if you want to access non-published client endpoints(%s).\n", strings.Join(hc.Endpoints(), ","))
-				handleError(ExitServerError, err)
+				handleError(c, ExitServerError, err)
 			}
 			if isConnectionError(err) {
-				handleError(ExitBadConnection, err)
+				handleError(c, ExitBadConnection, err)
 			}
 		}
 		if debug {

+ 2 - 2
etcdctl/ctlv2/command/watch_command.go

@@ -46,7 +46,7 @@ func NewWatchCommand() cli.Command {
 // watchCommandFunc executes the "watch" command.
 func watchCommandFunc(c *cli.Context, ki client.KeysAPI) {
 	if len(c.Args()) == 0 {
-		handleError(ExitBadArgs, errors.New("key required"))
+		handleError(c, ExitBadArgs, errors.New("key required"))
 	}
 	key := c.Args()[0]
 	recursive := c.Bool("recursive")
@@ -67,7 +67,7 @@ func watchCommandFunc(c *cli.Context, ki client.KeysAPI) {
 	for !stop {
 		resp, err := w.Next(context.TODO())
 		if err != nil {
-			handleError(ExitServerError, err)
+			handleError(c, ExitServerError, err)
 		}
 		if resp.Node.Dir {
 			continue