1
1
package cmd
2
2
3
3
import (
4
+ "context"
4
5
"errors"
5
6
"fmt"
6
7
"os"
7
8
9
+ "github.com/kubeshop/tracetest/cli/config"
8
10
"github.com/kubeshop/tracetest/cli/pkg/resourcemanager"
11
+ "github.com/kubeshop/tracetest/cli/ui"
9
12
10
13
"github.com/spf13/cobra"
11
14
)
12
15
13
- type RunFn func (cmd * cobra.Command , args []string ) (string , error )
16
+ type RunFn func (ctx context. Context , cmd * cobra.Command , args []string ) (string , error )
14
17
type CobraRunFn func (cmd * cobra.Command , args []string )
15
18
type MiddlewareWrapper func (RunFn ) RunFn
16
19
20
+ func rootCtx (cmd * cobra.Command ) context.Context {
21
+ // cobra does not correctly progpagate rootcmd context to sub commands,
22
+ // so we need to manually traverse the command tree to find the root context
23
+ if cmd == nil {
24
+ return nil
25
+ }
26
+
27
+ var (
28
+ ctx = cmd .Context ()
29
+ p = cmd .Parent ()
30
+ )
31
+ if cmd .Parent () == nil {
32
+ return ctx
33
+ }
34
+ for {
35
+ ctx = p .Context ()
36
+ p = p .Parent ()
37
+ if p == nil {
38
+ break
39
+ }
40
+ }
41
+ return ctx
42
+ }
43
+
17
44
func WithResultHandler (runFn RunFn ) CobraRunFn {
18
45
return func (cmd * cobra.Command , args []string ) {
19
- res , err := runFn (cmd , args )
46
+ // we need the root cmd context in case of an error caused rerun
47
+ ctx := rootCtx (cmd )
48
+
49
+ res , err := runFn (ctx , cmd , args )
20
50
21
51
if err != nil {
22
- OnError ( err )
52
+ handleError ( ctx , err )
23
53
return
24
54
}
25
55
@@ -29,6 +59,28 @@ func WithResultHandler(runFn RunFn) CobraRunFn {
29
59
}
30
60
}
31
61
62
+ func handleError (ctx context.Context , err error ) {
63
+ reqErr := resourcemanager.RequestError {}
64
+ if errors .As (err , & reqErr ) && reqErr .IsAuthError {
65
+ handleAuthError (ctx )
66
+ } else {
67
+ OnError (err )
68
+ }
69
+ }
70
+
71
+ func handleAuthError (ctx context.Context ) {
72
+ ui .DefaultUI .Warning ("Your authentication token has expired, please log in again." )
73
+ configurator .
74
+ WithOnFinish (func (ctx context.Context , _ config.Config ) {
75
+ retryCommand (ctx )
76
+ }).
77
+ ExecuteUserLogin (ctx , cliConfig )
78
+ }
79
+
80
+ func retryCommand (ctx context.Context ) {
81
+ handleRootExecErr (rootCmd .ExecuteContext (ctx ))
82
+ }
83
+
32
84
type errorMessageRenderer interface {
33
85
Render ()
34
86
}
@@ -66,7 +118,7 @@ func handleErrorMessage(err error) string {
66
118
67
119
func WithParamsHandler (validators ... Validator ) MiddlewareWrapper {
68
120
return func (runFn RunFn ) RunFn {
69
- return func (cmd * cobra.Command , args []string ) (string , error ) {
121
+ return func (ctx context. Context , cmd * cobra.Command , args []string ) (string , error ) {
70
122
errors := make ([]error , 0 )
71
123
72
124
for _ , validator := range validators {
@@ -82,7 +134,7 @@ func WithParamsHandler(validators ...Validator) MiddlewareWrapper {
82
134
return "" , fmt .Errorf (errorText )
83
135
}
84
136
85
- return runFn (cmd , args )
137
+ return runFn (ctx , cmd , args )
86
138
}
87
139
}
88
140
}
0 commit comments