Skip to content

Commit 507f19f

Browse files
author
gregorgololicic
committed
error handling implementation
1 parent 7e0ede8 commit 507f19f

10 files changed

Lines changed: 120 additions & 17 deletions

File tree

cmd/account/get/get.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,24 @@ func NewCmdGet(gateway gateway.IGateway, version string) *cobra.Command {
2323
Long: `
2424
Gets an account by address (address, balance, keys, code)`,
2525
Args: cobra.ExactArgs(1),
26-
Run: func(cmd *cobra.Command, args []string) {
26+
RunE: func(cmd *cobra.Command, args []string) error {
2727
if api != "" {
2828
gateway.SetAPIURL(api)
2929
}
3030

31-
account := gateway.GetAccount(args[0])
31+
account, err := gateway.GetAccount(args[0])
32+
33+
if err != nil {
34+
return err
35+
}
3236

3337
if !json {
3438
fmt.Println(account.String(filter))
3539
} else {
3640
fmt.Println(account.JSON(filter))
3741
}
42+
43+
return nil
3844
},
3945
}
4046

cmd/helpers.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package cmd
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"strconv"
7+
8+
"github.com/manifoldco/promptui"
9+
)
10+
11+
// PromptUrl enters discovery api url if missing
12+
func PromptUrl() {
13+
14+
validate := func(input string) error {
15+
_, err := strconv.ParseFloat(input, 64)
16+
if err != nil {
17+
return errors.New("Invalid number")
18+
}
19+
return nil
20+
}
21+
22+
prompt := promptui.Prompt{
23+
Label: "Number",
24+
Validate: validate,
25+
}
26+
27+
result, err := prompt.Run()
28+
29+
if err != nil {
30+
fmt.Printf("Prompt failed %v\n", err)
31+
return
32+
}
33+
34+
fmt.Printf("You choose %q\n", result)
35+
}

cmd/root.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,50 @@
11
package cmd
22

33
import (
4+
"errors"
5+
46
accountCmd "github.com/sideninja/flow-cli/cmd/account"
57
"github.com/sideninja/flow-cli/gateway"
68
"github.com/spf13/cobra"
79
)
810

9-
var cfgFile string
11+
// SilentErr is silent error passed through
12+
var SilentErr = errors.New("SilentErr")
1013

1114
// NewCmdRoot root command factory
1215
func NewCmdRoot(gateway gateway.IGateway, version string) *cobra.Command {
1316

1417
var (
1518
json bool
19+
//url string
1620
)
1721

1822
var rootCmd = &cobra.Command{
1923
Use: "flow",
2024
Short: "Flow CLI Tool",
2125
TraverseChildren: true,
26+
SilenceErrors: true,
27+
SilenceUsage: true,
2228
Long: `
2329
Flow CLI tool to interact with flow emulator.`,
2430
}
2531

32+
//rootCmd.PersistentFlags().StringVar(&url, "url", "", "url of discovery api")
33+
//viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
34+
35+
// here we add all commands:
2636
rootCmd.AddCommand(accountCmd.NewCmdAccount(gateway, version))
2737

38+
// always enabled version and json flags
2839
rootCmd.Flags().BoolP("version", "v", false, "show version information")
2940
rootCmd.PersistentFlags().BoolVarP(&json, "json", "j", false, "show output format as JSON")
3041

42+
// error handling for commands
43+
rootCmd.SetFlagErrorFunc(func(cmd *cobra.Command, err error) error {
44+
cmd.Printf("\n\033[31mError: %s\033[0m\n\n", err)
45+
cmd.Println(cmd.UsageString())
46+
return SilentErr
47+
})
48+
3149
return rootCmd
3250
}

gateway/gateway.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ import (
77
// IGateway interface defines all the getter methods
88
// needed by the cli to be implemented by each gateway
99
type IGateway interface {
10-
GetAccount(address string) *models.Account
10+
GetAccount(address string) (*models.Account, error)
1111
SetAPIURL(url string)
1212
}
1313

1414
// CreateGateway creates a gateway from a factory
1515
func CreateGateway(method string, url string) IGateway {
1616
// check if testing or rest setting and return test instance
17-
if method == "rest" {
17+
if method == models.REST {
1818
return &Rest{}
1919
}
2020

gateway/grpc.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package gateway
22

33
import (
44
"context"
5-
"log"
65

76
"github.com/sideninja/flow-cli/models"
87

@@ -24,11 +23,11 @@ func (g *GRPC) SetAPIURL(url string) {
2423
}
2524

2625
// GetAccount gets account by the address via grpc call
27-
func (g *GRPC) GetAccount(address string) *models.Account {
26+
func (g *GRPC) GetAccount(address string) (*models.Account, error) {
2827
flowClient, err := client.New(g.APIURL, grpc.WithInsecure())
2928

3029
if err != nil {
31-
log.Fatal(err)
30+
return nil, err
3231
}
3332

3433
// validation of params
@@ -39,8 +38,8 @@ func (g *GRPC) GetAccount(address string) *models.Account {
3938
)
4039

4140
if err != nil {
42-
log.Fatal(err)
41+
return nil, err
4342
}
4443

45-
return &models.Account{account}
44+
return &models.Account{account}, nil
4645
}

gateway/rest.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ func (r *Rest) SetAPIURL(url string) {
1111
}
1212

1313
// GetAccount gets account over rest api
14-
func (r *Rest) GetAccount(address string) *models.Account {
14+
func (r *Rest) GetAccount(address string) (*models.Account, error) {
1515
// not implemented
16-
return &models.Account{}
16+
return &models.Account{}, nil
1717
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.15
55
replace github.com/golang/protobuf v1.3.5 => google.golang.org/protobuf v1.23.0
66

77
require (
8+
github.com/manifoldco/promptui v0.8.0
89
github.com/mitchellh/go-homedir v1.1.0
910
github.com/onflow/flow-go-sdk v0.13.1
1011
github.com/spf13/cobra v1.1.1

go.sum

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf
7171
github.com/cespare/xxhash/v2 v2.0.1-0.20190104013014-3767db7a7e18/go.mod h1:HD5P3vAIAh+Y2GAxg0PrPN1P8WkepXGpjbUPDHJqqKM=
7272
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
7373
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
74+
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
7475
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
7576
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
7677
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
@@ -210,6 +211,8 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
210211
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
211212
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
212213
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
214+
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU=
215+
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU=
213216
github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
214217
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
215218
github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
@@ -222,18 +225,25 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
222225
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
223226
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
224227
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
228+
github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a h1:weJVJJRzAJBFRlAiJQROKQs8oC9vOxvm4rZmBBk0ONw=
229+
github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
225230
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
226231
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
232+
github.com/manifoldco/promptui v0.8.0 h1:R95mMF+McvXZQ7j1g8ucVZE1gLP3Sv6j9vlF9kyRqQo=
233+
github.com/manifoldco/promptui v0.8.0/go.mod h1:n4zTdgP0vr0S3w7/O/g98U+e0gwLScEXGwov2nIKuGQ=
227234
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
228235
github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
229236
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
237+
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
230238
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
231239
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
232240
github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
233241
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
242+
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
234243
github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
235244
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
236245
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
246+
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
237247
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
238248
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
239249
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
@@ -453,6 +463,7 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h
453463
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
454464
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
455465
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
466+
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
456467
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
457468
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
458469
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

main.go

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
package main
22

33
import (
4+
"errors"
45
"fmt"
56
"os"
67

7-
cmd "github.com/sideninja/flow-cli/cmd"
8+
"github.com/onflow/flow-go-sdk/client"
9+
"github.com/sideninja/flow-cli/cmd"
10+
cliCmd "github.com/sideninja/flow-cli/cmd"
811
"github.com/sideninja/flow-cli/gateway"
12+
"github.com/sideninja/flow-cli/models"
913
"github.com/spf13/viper"
14+
"google.golang.org/grpc/codes"
1015
)
1116

1217
func init() {
@@ -26,14 +31,38 @@ func init() {
2631
func main() {
2732

2833
APIURL := viper.GetString("APIURL")
29-
30-
gateway := gateway.CreateGateway("", APIURL)
3134
version := "1.0"
3235

33-
rootCmd := cmd.NewCmdRoot(gateway, version)
36+
gateway := gateway.CreateGateway(models.GRPC, APIURL)
37+
38+
rootCmd := cliCmd.NewCmdRoot(gateway, version)
3439

3540
if err := rootCmd.Execute(); err != nil {
36-
fmt.Println(err)
41+
handleError(err)
3742
os.Exit(1)
3843
}
3944
}
45+
46+
func handleError(err error) {
47+
if err != cmd.SilentErr {
48+
// check if error is grpc error
49+
rpcError := client.RPCError{}
50+
if errors.As(err, &rpcError) {
51+
handleGrpcError(rpcError)
52+
} else { // unhandeled error - can be improved
53+
fmt.Printf("\n\033[31mUnhandeled Error: %s\033[0m\n\n", err)
54+
}
55+
}
56+
}
57+
58+
func handleGrpcError(rpcError client.RPCError) {
59+
switch rpcError.GRPCStatus().Code() {
60+
case codes.InvalidArgument:
61+
fmt.Printf("\n\033[31mInvalid Arguments: %s\033[0m\n\n", rpcError.GRPCStatus().Message())
62+
case codes.Unavailable:
63+
fmt.Printf("\nConnection to Flow Emulator was not successful, please make sure your api url is correct. You can set it by: flow [COMMAND] --api URL \n")
64+
fmt.Printf("\n\033[31mConnection Error: %s\033[0m\n\n", rpcError.GRPCStatus().Message())
65+
default:
66+
fmt.Printf("\n\033[31mUnhandeled Error: %s\033[0m\n\n", rpcError.GRPCStatus().Err())
67+
}
68+
}

models/constants.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package models
2+
3+
var GRPC string = "grpc"
4+
var REST string = "rest"

0 commit comments

Comments
 (0)