错误必须写到 stderr,使用 fmt.Fprintln(os.Stderr, err) 或 log.New(os.Stderr, "", 0).Println(err);错误信息应简洁具体,如 "open config.yaml: permission denied",不加 ERROR 等前缀;通过 %w 保留原始错误链,支持 errors.Is/As 检查;在 main 中统一处理错误输出与退出码,避免中间函数调用 os.Exit。

Go CLI 程序输出错误,核心是:用 os.Stderr 输出、不带多余前缀、末尾不加换行(由调用者控制)、错误信息清晰具体、不掩盖原始错误链。
终端程序区分标准输出(stdout)和标准错误(stderr),前者用于正常结果,后者专用于错误和警告。用户可能重定向 stdout(如 mycmd > out.txt),但 stderr 仍会显示在终端,确保错误不被丢弃。
正确做法:
fmt.Fprintln(os.Stderr, "error: ...")
log.New(os.Stderr, "", 0).Println("error: ...")(避免全局 log.SetOutput 影响其他部分)fmt.Println("error: ...")(默认写到 stdout)不要自动加 ERROR:、[ERR] 或时间戳——CLI 用户习惯阅读原生、紧凑的错误描述。前缀应由上层统一处理(比如主函数统一包装),或完全交由调用方决定。
立即学习“go语言免费学习笔记(深入)”;
好例子:
open config.yaml: permission denied(直接复用 err.Error())invalid port number "abc": strconv.ParseInt: parsing "abc": invalid syntax坏例子:
ERROR: open config.yaml: permission denied(前缀多余)[2024-05-12 10:30:00] FATAL: ...(时间戳+级别对 CLI 不必要)%w 和 errors.Join
不要用 fmt.Sprintf("failed to read %s: %v", file, err) 吞掉原始 error。要支持错误检查(errors.Is / errors.As)和展开(errors.Unwrap)。
推荐写法:
return fmt.Errorf("read config file %q: %w", path, err)errors.Join(err1, err2)(Go 1.20+)errors.Unwrap 或 errors.Format(需自定义)展示全链,但多数 CLI 直接输出最外层 err.Error() 即可,够用且干净在 main() 函数中,用一个 if err != nil 块集中处理所有错误输出和退出码,保持逻辑清晰。
典型结构:
func main() {
if err := run(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}注意:
os.Exit 或 log.Fatal——这会让测试变困难、无法拦截错误interface{ ExitCode() int },然后在 main 中判断基本上就这些。不复杂但容易忽略——关键是把 stderr 当“错误专用通道”,把 error 当“可传递、可检查的数据”,而不是字符串日志。
以上就是Golang CLI程序中如何输出错误_Golang终端程序错误提示规范的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号