Skip to content
This repository has been archived by the owner on Nov 22, 2022. It is now read-only.

Commit

Permalink
refactor: enhance error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
profclems committed Aug 15, 2020
1 parent 4306c23 commit 09ba137
Show file tree
Hide file tree
Showing 29 changed files with 525 additions and 96 deletions.
4 changes: 2 additions & 2 deletions Makefile
Expand Up @@ -20,9 +20,9 @@ GO_LDFLAGS := -X main.version=$(GLAB_VERSION) $(GO_LDFLAGS)
GO_LDFLAGS := -X main.build=$(BUILD_DATE) $(GO_LDFLAGS)

build:
go build -trimpath -ldflags "$(GO_LDFLAGS)" -o ./bin/glab ./cmd/glab
go build -trimpath -ldflags "$(GO_LDFLAGS) -X main.usageMode=prod" -o ./bin/glab ./cmd/glab
run:
go run -trimpath -ldflags "$(GO_LDFLAGS)" ./cmd/glab $(var)
go run -trimpath -ldflags "$(GO_LDFLAGS) -X main.usageMode=dev" ./cmd/glab $(var)
test:
go test ./...
rt: #Test release
Expand Down
72 changes: 68 additions & 4 deletions cmd/glab/main.go
@@ -1,22 +1,86 @@
package main

import (
"errors"
"fmt"
"glab/commands"
"glab/internal/utils"
"io"
"net"
"os"
"regexp"
"strings"

"github.com/spf13/cobra"
"glab/commands"
"glab/internal/config"
)

// Version is set at build
var version string

// build is set at build
var build string
// usage mode is set at build to either "dev" or "prod" depending how binary is created
var usageMode string
var debug bool

func main() {
commands.Version = version
commands.Build = build
if err := commands.Execute(); err != nil {
fmt.Println(err)

initConfig()
if usageMode == "dev" {
debug = true
}
if cmd, err := commands.Execute(); err != nil {
printError(os.Stderr, err, cmd, debug)
os.Exit(1)
}
}

func initConfig() {
config.SetGlobalPathDir()
config.UseGlobalConfig = true

if config.GetEnv("GITLAB_URI") == "NOTFOUND" || config.GetEnv("GITLAB_URI") == "OK" {
config.SetEnv("GITLAB_URI", "https://gitlab.com")
}
if config.GetEnv("GIT_REMOTE_URL_VAR") == "NOTFOUND" || config.GetEnv("GIT_REMOTE_URL_VAR") == "OK" {
config.SetEnv("GIT_REMOTE_URL_VAR", "origin")
}

config.UseGlobalConfig = false
}

func printError(out io.Writer, err error, cmd *cobra.Command, debug bool) {
if err == utils.SilentError {
return
}

var dnsError *net.DNSError
if errors.As(err, &dnsError) {
_, _ = fmt.Fprintf(out, "error connecting to %s\n", dnsError.Name)
if debug {
_, _ = fmt.Fprintln(out, dnsError)
}
_, _ = fmt.Fprintln(out, "check your internet connection or status.gitlab.com or 'Run sudo gitlab-ctl status' on your server if self-hosted")
return
}

re := regexp.MustCompile(`(?s){(.*)}`)
m := re.FindAllStringSubmatch(err.Error(), -1)
if len(m) != 0 {
if len(m[0]) >= 1 {
_, _ = fmt.Fprintln(out, m[0][1])
}
} else {
_, _ = fmt.Fprintln(out, err)
}

var flagError *utils.FlagError
if errors.As(err, &flagError) || strings.HasPrefix(err.Error(), "unknown command ") {
if !strings.HasSuffix(err.Error(), "\n") {
_, _ = fmt.Fprintln(out)
}
_, _ = fmt.Fprintln(out, cmd.UsageString())
}
}
90 changes: 90 additions & 0 deletions cmd/glab/main_test.go
@@ -0,0 +1,90 @@
package main

import (
"bytes"
"flag"
"fmt"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"glab/internal/config"
"glab/internal/utils"
"math/rand"
"net"
"strconv"
"testing"
"time"
)

// Test started when the test binary is started
// and calls the main function
func TestGlab(t *testing.T) {
rand.Seed(time.Now().UnixNano())
flag.Set("test", "../coverage-" + strconv.Itoa(int(rand.Uint64())) + ".out")
main()
}

func Test_printError(t *testing.T) {
cmd := &cobra.Command{}

type args struct {
err error
cmd *cobra.Command
debug bool
}
tests := []struct {
name string
args args
wantOut string
}{
{
name: "generic error",
args: args{
err: errors.New("the app exploded"),
cmd: nil,
debug: false,
},
wantOut: "the app exploded\n",
},
{
name: "DNS error",
args: args{
err: fmt.Errorf("DNS oopsie: %w", &net.DNSError{
Name: config.GetEnv("GITLAB_URI")+"/api/v4",
}),
cmd: nil,
debug: false,
},
wantOut: `error connecting to `+config.GetEnv("GITLAB_URI")+`/api/v4
check your internet connection or status.gitlab.com or 'Run sudo gitlab-ctl status' on your server if self-hosted
`,
},
{
name: "Cobra flag error",
args: args{
err: &utils.FlagError{Err: errors.New("unknown flag --foo")},
cmd: cmd,
debug: false,
},
wantOut: "unknown flag --foo\n\nUsage:\n\n",
},
{
name: "unknown Cobra command error",
args: args{
err: errors.New("unknown command foo"),
cmd: cmd,
debug: false,
},
wantOut: "unknown command foo\n\nUsage:\n\n",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
out := &bytes.Buffer{}
printError(out, tt.args.err, tt.args.cmd, tt.args.debug)
if gotOut := out.String(); gotOut != tt.wantOut {
t.Errorf("printError() = %q, want %q", gotOut, tt.wantOut)
}
})
}
}
9 changes: 5 additions & 4 deletions commands/issue_close.go
Expand Up @@ -6,7 +6,6 @@ import (
"github.com/xanzy/go-gitlab"
"glab/internal/git"
"glab/internal/manip"
"log"
"strings"
)

Expand All @@ -16,10 +15,10 @@ var issueCloseCmd = &cobra.Command{
Long: ``,
Aliases: []string{"unsub"},
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) > 1 {
cmdErr(cmd, args)
return
return nil
}
if len(args) > 0 {
issueID := strings.TrimSpace(args[0])
Expand All @@ -34,7 +33,7 @@ var issueCloseCmd = &cobra.Command{
fmt.Println("Closing Issue...")
issue, resp, err := gitlabClient.Issues.UpdateIssue(repo, manip.StringToInt(i2), l)
if err != nil {
log.Fatal(err)
return err
}
if isSuccessful(resp.StatusCode) {
fmt.Println("Issue #" + i2 + " closed")
Expand All @@ -47,7 +46,9 @@ var issueCloseCmd = &cobra.Command{
}
} else {
cmdErr(cmd, args)
return nil
}
return nil
},
}

Expand Down
18 changes: 9 additions & 9 deletions commands/issue_create.go
@@ -1,7 +1,6 @@
package commands

import (
"log"
"strings"

"github.com/spf13/cobra"
Expand All @@ -16,10 +15,10 @@ var issueCreateCmd = &cobra.Command{
Long: ``,
Aliases: []string{"new"},
Args: cobra.ExactArgs(0),
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) > 0 {
cmdErr(cmd, args)
return
return nil
}

l := &gitlab.CreateIssueOptions{}
Expand All @@ -31,11 +30,6 @@ var issueCreateCmd = &cobra.Command{
} else {
issueTitle = manip.AskQuestionWithInput("Title", "", true)
}
if label, _ := cmd.Flags().GetString("label"); label != "" {
issueLabel = strings.Trim(label, "[] ")
} else {
issueLabel = manip.AskQuestionWithInput("Label(s) [Comma Separated]", "", false)
}
if description, _ := cmd.Flags().GetString("description"); description != "" {
issueDescription = strings.Trim(description, " ")
} else {
Expand All @@ -49,6 +43,11 @@ var issueCreateCmd = &cobra.Command{
})
}
}
if label, _ := cmd.Flags().GetString("label"); label != "" {
issueLabel = strings.Trim(label, "[] ")
} else {
issueLabel = manip.AskQuestionWithInput("Label(s) [Comma Separated]", "", false)
}
l.Title = gitlab.String(issueTitle)
l.Labels = &gitlab.Labels{issueLabel}
l.Description = &issueDescription
Expand Down Expand Up @@ -81,9 +80,10 @@ var issueCreateCmd = &cobra.Command{
}
issue, _, err := gitlabClient.Issues.CreateIssue(repo, l)
if err != nil {
log.Fatal(err)
return err
}
displayIssue(issue)
return nil
},
}

Expand Down
5 changes: 3 additions & 2 deletions commands/issue_delete.go
Expand Up @@ -14,10 +14,10 @@ var issueDeleteCmd = &cobra.Command{
Long: ``,
Aliases: []string{"del"},
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) > 1 {
cmdErr(cmd, args)
return
return nil
}
if len(args) > 0 {
issueID := strings.TrimSpace(args[0])
Expand All @@ -40,6 +40,7 @@ var issueDeleteCmd = &cobra.Command{
} else {
cmdErr(cmd, args)
}
return nil
},
}

Expand Down
6 changes: 3 additions & 3 deletions commands/issue_list.go
Expand Up @@ -4,7 +4,6 @@ import (
"github.com/spf13/cobra"
"github.com/xanzy/go-gitlab"
"glab/internal/git"
"log"
)

var issueListCmd = &cobra.Command{
Expand All @@ -13,7 +12,7 @@ var issueListCmd = &cobra.Command{
Long: ``,
Aliases: []string{"ls"},
Args: cobra.ExactArgs(0),
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
var state string
if lb, _ := cmd.Flags().GetBool("all"); lb {
state = "all"
Expand Down Expand Up @@ -45,9 +44,10 @@ var issueListCmd = &cobra.Command{
}
issues, _, err := gitlabClient.Issues.ListProjectIssues(repo, l)
if err != nil {
log.Fatal(err)
return err
}
displayAllIssues(issues)
return nil

},
}
Expand Down

0 comments on commit 09ba137

Please sign in to comment.