Skip to content

fix(cli): 输出被 SilenceErrors 吞掉的错误,父命令遇未知子命令报错 - #15

Open
shushenghong wants to merge 1 commit into
studyzy:mainfrom
shushenghong:fix/print-silenced-errors
Open

shushenghong wants to merge 1 commit into
studyzy:mainfrom
shushenghong:fix/print-silenced-errors

Conversation

@shushenghong

Copy link
Copy Markdown
Contributor

问题

rootCmd 设置了 SilenceErrors: true,而 Execute() 拿到错误后只 os.Exit(1)、不打印,导致两类「静默失败」,对 AI Agent 尤其致命(看不到原因,只能猜):

  1. cobra 层错误零输出:未知参数、位置参数个数不对、RunE 直接 return err 的错误,都只有退出码 1、stdout/stderr 全空。
    • tapd comment add --current-user=xx ...(comment add 没有这个 flag)
    • tapd bug update --id=123 --status=resolved(id 是位置参数)
    • tapd comment list --fields=id
  2. 写错子命令被当成成功:cobra 只在根命令校验子命令名,tapd bug comment add ... 会打印 bug 的 help 后以退出码 0 返回,Agent 以为评论已发出。

我们在实际使用中,几次因为这类问题导致评论丢失、bug 状态没改却被当作已完成。

修复

  • Execute() 改用 ExecuteC(),把未处理的错误统一以 JSON 输出到 stderr,格式与现有 output.PrintError 一致:
    {"error":"command_error","message":"unknown flag: --id","hint":"Run 'tapd bug update --help' for usage"}
    退出码保持 1 不变。
  • 新增 guardUnknownSubcommands:给没有 Run 的父命令补兜底 RunE。有多余参数时报 unknown command "comment" for "tapd bug",没有参数时照常输出 help。这些父命令通过 Annotation 标记,跳过客户端初始化,所以没有凭据时也能看 help、正常报错。
  • 子命令自己处理的错误(先 PrintError 再 os.Exit)不经过这里,不会重复输出。

验证

命令 修复前 修复后
tapd bug update --id=1 exit 1,无输出 exit 1,unknown flag: --id
tapd comment add --current-user=x ... exit 1,无输出 exit 1,unknown flag: --current-user
tapd bug update exit 1,无输出 exit 1,accepts 1 arg(s), received 0
tapd bug comment add exit 0,打印 help exit 1,unknown command "comment" for "tapd bug"
tapd bug / tapd bug --help help,exit 0 不变
tapd bug show <id> 等正常命令 — 不变
  • 新增 internal/cmd/root_errors_test.go,覆盖未知子命令、父命令输出 help、已知子命令正常执行、错误 JSON 格式和 hint。
  • go vet ./...、go test -race ./... 全部通过。

🤖 Generated with Claude Code

rootCmd 开启了 SilenceErrors,Execute() 拿到错误只 os.Exit(1) 不打印,导致:
- 未知参数(如 comment add --current-user、bug update --id=1)、位置参数个数不对等
  cobra 层错误,以及 RunE 直接 return 的错误,调用方只看到退出码 1、零输出
- 非根父命令不校验子命令名,`tapd bug comment add` 打印 help 后以退出码 0 返回,
  AI Agent 误以为评论已发出

修复:
- Execute() 改用 ExecuteC,统一以 JSON 输出到 stderr(error=command_error,hint 指向对应命令的 --help)
- guardUnknownSubcommands 给无 Run 的父命令补兜底 RunE:有多余参数报 unknown command,否则输出 help;
  这类父命令跳过客户端初始化,无凭据时也能正常报错/看 help

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant