Skip to content

Commit a0afa9b

Browse files
committed
refactor: Add cmd.Execute function which properly tears down after a panic
1 parent eb706be commit a0afa9b

File tree

5 files changed

+30
-32
lines changed

5 files changed

+30
-32
lines changed

cmd/cmd.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package cmd
22

33
import (
4+
"errors"
5+
"fmt"
46
"log/slog"
57
"net/http"
68
"os"
79
"os/signal"
810
"path/filepath"
11+
"runtime/debug"
912
"syscall"
1013

1114
"github.com/clevyr/kubedb/cmd/dump"
@@ -22,7 +25,7 @@ import (
2225
"github.com/spf13/cobra"
2326
)
2427

25-
func NewCommand() *cobra.Command {
28+
func New() *cobra.Command {
2629
name := "kubedb"
2730
var annotations map[string]string
2831
if filepath.Base(os.Args[0]) == "kubectl-db" {
@@ -40,6 +43,7 @@ func NewCommand() *cobra.Command {
4043
Version: buildVersion(),
4144
DisableAutoGenTag: true,
4245
Annotations: annotations,
46+
SilenceErrors: true,
4347

4448
PersistentPreRunE: preRun,
4549
}
@@ -90,7 +94,6 @@ func preRun(cmd *cobra.Command, _ []string) error {
9094
cmd.SetContext(ctx)
9195

9296
log.InitGlobal(cmd)
93-
cmd.Root().SilenceErrors = true
9497

9598
if config.Global.HealthchecksPingURL != "" {
9699
if handler, err := notifier.NewHealthchecks(config.Global.HealthchecksPingURL); err != nil {
@@ -113,10 +116,29 @@ func preRun(cmd *cobra.Command, _ []string) error {
113116
return nil
114117
}
115118

119+
var errPanic = errors.New("panic")
120+
116121
func buildVersion() string {
117122
result := util.GetVersion()
118123
if commit := util.GetCommit(); commit != "" {
119124
result += " (" + commit + ")"
120125
}
121126
return result
122127
}
128+
129+
func Execute(cmd *cobra.Command) (err error) {
130+
if cmd == nil {
131+
cmd = New()
132+
}
133+
134+
defer finalizer.PostRun(err)
135+
defer func() {
136+
if msg := recover(); msg != nil {
137+
slog.Error("Recovered from panic", "error", msg)
138+
err = fmt.Errorf("%w: %v\n\n%s", errPanic, msg, string(debug.Stack()))
139+
}
140+
}()
141+
142+
err = cmd.Execute()
143+
return
144+
}

internal/generate/completions/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const (
1616
)
1717

1818
func main() {
19-
rootCmd := cmd.NewCommand()
19+
rootCmd := cmd.New()
2020
var buf bytes.Buffer
2121
rootCmd.SetOut(&buf)
2222

internal/generate/docs/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func main() {
2323
log.Fatal(fmt.Errorf("failed to mkdir: %w", err))
2424
}
2525

26-
rootCmd := cmd.NewCommand()
26+
rootCmd := cmd.New()
2727

2828
err = doc.GenMarkdownTree(rootCmd, output)
2929
if err != nil {

internal/generate/manpages/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func main() {
3535
panic(err)
3636
}
3737

38-
rootCmd := cmd.NewCommand()
38+
rootCmd := cmd.New()
3939
rootName := rootCmd.Name()
4040

4141
date, err := time.Parse(time.RFC3339, dateParam)

main.go

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,18 @@
11
package main
22

33
import (
4-
"errors"
5-
"fmt"
6-
"io"
74
"log/slog"
85
"os"
9-
"runtime/debug"
106

117
"gabe565.com/utils/slogx"
128
"github.com/clevyr/kubedb/cmd"
13-
"github.com/clevyr/kubedb/internal/finalizer"
149
"github.com/clevyr/kubedb/internal/log"
1510
)
1611

17-
var errPanic = errors.New("panic")
18-
1912
func main() {
20-
defer func() {
21-
var err error
22-
var status int
23-
if msg := recover(); msg != nil {
24-
status = 1
25-
slog.Error("Recovered from panic", "error", msg)
26-
err = fmt.Errorf("%w: %v\n\n%s", errPanic, msg, string(debug.Stack()))
27-
_, _ = io.WriteString(os.Stderr, err.Error())
28-
}
29-
finalizer.PostRun(err)
30-
os.Exit(status)
31-
}()
32-
3313
log.Init(os.Stderr, slogx.LevelInfo, slogx.FormatAuto)
34-
rootCmd := cmd.NewCommand()
35-
if err := rootCmd.Execute(); err != nil {
36-
if rootCmd.SilenceErrors {
37-
slog.Error(err.Error())
38-
}
39-
finalizer.PostRun(err)
40-
os.Exit(1) //nolint:gocritic
14+
if err := cmd.Execute(cmd.New()); err != nil {
15+
slog.Error(err.Error())
16+
os.Exit(1)
4117
}
4218
}

0 commit comments

Comments
 (0)