信息发布→ 登录 注册 退出

Golang CLI程序中如何输出错误_Golang终端程序错误提示规范

发布时间:2025-12-03

点击量:
错误必须写到 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。

golang cli程序中如何输出错误_golang终端程序错误提示规范

Go CLI 程序输出错误,核心是:用 os.Stderr 输出、不带多余前缀、末尾不加换行(由调用者控制)、错误信息清晰具体、不掩盖原始错误链。

错误必须写到 stderr,而不是 stdout

终端程序区分标准输出(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 用户习惯阅读原生、紧凑的错误描述。前缀应由上层统一处理(比如主函数统一包装),或完全交由调用方决定。

好例子:

  • open config.yaml: permission denied(直接复用 err.Error()
  • invalid port number "abc": strconv.ParseInt: parsing "abc": invalid syntax

坏例子:

  • ERROR: open config.yaml: permission denied(前缀多余)
  • [2025-05-12 10:30:00] FATAL: ...(时间戳+级别对 CLI 不必要)

保留错误上下文与原始原因,善用 %werrors.Join

不要用 fmt.Sprintf("failed to read %s: %v", file, err) 吞掉原始 error。要支持错误检查(errors.Is / errors.As)和展开(errors.Unwrap)。

Remover Remover

几秒钟去除图中不需要的元素

Remover 304 查看详情 Remover

推荐写法:

  • return fmt.Errorf("read config file %q: %w", path, err)
  • 多个错误合并:errors.Join(err1, err2)(Go 1.20+)
  • 最终输出时,可调用 errors.Unwraperrors.Format(需自定义)展示全链,但多数 CLI 直接输出最外层 err.Error() 即可,够用且干净

主函数结尾统一处理错误退出

main() 函数中,用一个 if err != nil 块集中处理所有错误输出和退出码,保持逻辑清晰。

典型结构:

func main() {
    if err := run(); err != nil {
        fmt.Fprintln(os.Stderr, err)
        os.Exit(1)
    }
}

注意:

  • 不要在中间函数里调用 os.Exitlog.Fatal——这会让测试变困难、无法拦截错误
  • 若需不同退出码(如 2 表示命令行参数错),可用自定义错误类型实现 interface{ ExitCode() int },然后在 main 中判断

基本上就这些。不复杂但容易忽略——关键是把 stderr 当“错误专用通道”,把 error 当“可传递、可检查的数据”,而不是字符串日志。

以上就是Golang CLI程序中如何输出错误_Golang终端程序错误提示规范的详细内容,更多请关注其它相关文章!


相关文章: 护手霜蹭到袖口上了如何清洗? 怎样避免留下一圈油印?  铁路12306的积分有效期是多久_铁路12306积分有效期说明  小米14应用无法联网原因分析_小米14网络权限修复  j*a toString()的覆盖  将HTML Canvas内容转换为可上传的图像文件(File对象)  J*aScript动态修改指定div内所有a标签样式指南  LINUX怎么安装MySQL_LINUX数据库安装配置教程  文本文档写html代码怎么运行_文本文档html代码运行步骤【教程】  PHP字符串中复杂变量插值的最佳实践与语法解析  如何在CSS中使用visited与link控制链接颜色_visited link伪类配合  如何提高微信支付的安全性_微信支付安全防护与设置建议  AO3最新入口2025公告_AO3中文官网合集  美团外卖商家服务中心入口 美团商家版官网入口  C++20的source_location是什么_C++在编译期获取源码位置信息用于日志和断言  机器学习中对数变换预测结果的反向还原  win11开机启动修复循环怎么办 Win11无法进入系统高级启动解决方法【修复】  拼多多购物车商品数量无法修改如何处理 拼多多购物车操作优化方法  外媒分析《GTA6》定价:卖100美元可以但真没必要!  夸克浏览器图书入口 夸克手机浏览器阅读入口  Lar*el如何生成PDF或Excel文件_Lar*el文档导出工具与使用教程  sublime如何处理大型CSV文件的列对齐_sublime高级表格编辑插件指南  Typer应用中动态命令行参数的解析与处理  CSS Box Model与弹性按钮:维持布局稳定的动画实践  SteamMachine定价或为699美元 大家想入手吗?  抖音网页版快捷访问 抖音网页版网页版入口操作教程  Adobe PDF表单中利用J*aScript解析与格式化日期组件的教程  邮编格式怎么匹配地址_根据邮编格式快速匹配详细地址的技巧  Lar*el Excel导入时生成自定义递增ID的策略与实践  蛙漫官方正版入口 蛙漫网页在线全集免费观看  浏览器打开即用 美图秀秀网页版入口  Golang如何处理RPC请求负载均衡_Golang RPC请求负载均衡策略与实践  vivo手机互传视频怎么操作_vivo手机互传视频详细传输方法  微信网页版官方快速登录入口 微信网页版网页版账号直达  特斯拉自动驾驶房车计划曝光 原型车将于2027年亮相  中兴BladeV30怎样用测距估书架层高_iPhone中兴BladeV30测距估书架层高【家装参考】  c++如何使用折叠表达式(Fold Expressions)_c++17可变参数模板新技巧  蛙漫2日版入口 WAMAN2(日版)无删减漫画官网链接  12306选座怎么选到特殊座位_12306特殊座位选择注意事项  Golang如何安装Swagger工具_GoSwagger文档生成环境  构建轻量级网站内部消息系统:Formspree 集成指南  Pyrogram与g4f集成:异步编程实践与常见错误解决  J*aScript中管理异步API调用:确保操作顺序与数据一致性  怎样在Excel中做仪表盘_Excel仪表盘设计与关键指标展示方法  谷歌邮箱网页版官方页面入口 谷歌邮箱网页端快速访问  小红书怎么解除第三方平台绑定_小红书多平台登录解绑方法介绍  css绝对定位元素脱离父容器怎么办_确保父元素position非static  C#如何安全地从用户上传的XML文件中读取数据? 验证与清理策略  如何将一个大型PHP应用拆分为多个Composer包_微服务与模块化架构的Composer实践  京东京造J1和网易云音乐氧气真无线有什么不同_国产电商蓝牙耳机音质对比  FullCalendar 自定义按钮样式定制指南 

在线客服
服务热线

服务热线

4008988990

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!