95 lines
2.2 KiB
Go
95 lines
2.2 KiB
Go
package app
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/executor"
|
|
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/recovery"
|
|
)
|
|
|
|
func captureRuntimeFailure(invocation executor.Invocation, rawErr, wrappedErr error) {
|
|
if rawErr == nil && wrappedErr == nil {
|
|
return
|
|
}
|
|
store := recovery.NewStore(defaultConfigDir())
|
|
if store == nil || !store.Enabled() {
|
|
return
|
|
}
|
|
input := recovery.CaptureInput{
|
|
CommandPath: runtimeCommandPath(invocation),
|
|
ServerID: strings.TrimSpace(invocation.CanonicalProduct),
|
|
ToolName: strings.TrimSpace(invocation.Tool),
|
|
Args: cloneRecoveryArgs(invocation.Params),
|
|
Argv: append([]string(nil), os.Args[1:]...),
|
|
RawErr: rawErr,
|
|
WrappedErr: wrappedErr,
|
|
}
|
|
_, _ = store.Capture(recovery.BuildContext(input), recovery.BuildReplay(input))
|
|
}
|
|
|
|
func runtimeCommandPath(invocation executor.Invocation) []string {
|
|
if path := currentCommandPath(); len(path) > 0 {
|
|
return path
|
|
}
|
|
if legacy := strings.Fields(strings.TrimSpace(invocation.LegacyPath)); len(legacy) > 0 {
|
|
return legacy
|
|
}
|
|
if product := strings.TrimSpace(invocation.CanonicalProduct); product != "" {
|
|
if tool := strings.TrimSpace(invocation.Tool); tool != "" {
|
|
return []string{product, tool}
|
|
}
|
|
return []string{product}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func currentCommandPath() []string {
|
|
boolFlags := map[string]struct{}{
|
|
"--verbose": {},
|
|
"-v": {},
|
|
"--debug": {},
|
|
"--mock": {},
|
|
"--dry-run": {},
|
|
"--yes": {},
|
|
"-y": {},
|
|
"--help": {},
|
|
"-h": {},
|
|
"--json": {},
|
|
}
|
|
path := make([]string, 0, len(os.Args))
|
|
skipNext := false
|
|
for _, arg := range os.Args[1:] {
|
|
if skipNext {
|
|
skipNext = false
|
|
continue
|
|
}
|
|
if arg == "--" {
|
|
break
|
|
}
|
|
if strings.HasPrefix(arg, "-") {
|
|
if strings.Contains(arg, "=") {
|
|
continue
|
|
}
|
|
if _, ok := boolFlags[arg]; ok {
|
|
continue
|
|
}
|
|
skipNext = true
|
|
continue
|
|
}
|
|
path = append(path, arg)
|
|
}
|
|
return path
|
|
}
|
|
|
|
func cloneRecoveryArgs(args map[string]any) map[string]any {
|
|
if len(args) == 0 {
|
|
return nil
|
|
}
|
|
out := make(map[string]any, len(args))
|
|
for key, value := range args {
|
|
out[key] = value
|
|
}
|
|
return out
|
|
}
|