Golang测试中如何断言错误类型
发布时间 - 2026-01-08 00:00:00 点击率:次errors.Is用于安全判断错误链中是否包含特定错误,errors.As用于提取具体错误类型;二者均递归遍历错误链,避免直接比较或字符串匹配;自定义错误需实现Unwrap方法。
用 errors.Is 判断是否为特定错误
Go 1.13 引入的 errors.Is 是最常用、也最安全的方式,用于判断一个错误是否「等于」某个已知错误(包括底层包装链中的目标错误)。它不依赖指针相等,而是递归检查错误链中是否存在匹配项。
err := doSomething()
if !errors.Is(err, io.EOF) {
t.Fatal("expected io.EOF, got:", err)
}常见误用是直接用 == 比较,这在错误被 fmt.Errorf("wrap: %w", err) 包装后必然失败。只要错误可能被包装(绝大多数标准库和现代 Go 库都这么做),就必须用 errors.Is。
用 errors.As 提取具体错误类型
当需要访问错误的字段或方法(比如 *os.PathError 的 Path 字段),就得用 errors.As 将错误解包成具体类型:
var pathErr *os.PathError
if errors.As(err, &pathErr) {
if pathE
rr.Path == "/tmp/data.txt" {
// 处理特定路径的错误
}
}注意三点:
立即学习“go语言免费学习笔记(深入)”;
- 第二个参数必须是指向目标类型的指针(
&pathErr) -
errors.As同样遍历整个错误链,找到第一个匹配的类型即返回 true - 如果只是想确认类型存在而不需变量,仍得声明变量并传地址,无法跳过
避免用 reflect.TypeOf 或 error.Error() 做类型判断
有人会写 strings.Contains(err.Error(), "permission denied") 或 reflect.TypeOf(err).Name() == "PathError",这两种方式都不可靠:
-
Error()返回字符串可能被多层包装修改,且不同语言环境输出不同 -
reflect.TypeOf只看最外层类型,对fmt.Errorf("failed: %w", &os.PathError{})会返回errorString,而非PathError - 标准库错误类型(如
os.ErrNotExist)本身是变量,应优先用errors.Is对比,而不是靠名字或字符串猜
自定义错误类型要实现 Unwrap 方法才能被正确识别
如果你自己定义了带包装能力的错误类型,必须显式实现 Unwrap() error 方法,否则 errors.Is 和 errors.As 无法穿透到内层:
type MyError struct {
msg string
orig error
}
func (e MyError) Error() string { return e.msg }
func (e MyError) Unwrap() error { return e.orig } // 必须有这一行
漏掉 Unwrap 是测试中错误断言失效的高频原因——外部调用方根本「看不到」你包装的原始错误。
# go
# golang
# ai
# golang测试
# 标准库
# Error
# 字符串
# 递归
# 指针
# typeof
# 遍历
# 自定义
# 链中
# 都不
# 第一个
# 你自己
# 第二个
# 就得
# 三点
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
郑州企业网站制作公司,郑州招聘网站有哪些?
ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法
Laravel怎么调用外部API_Laravel Http Client客户端使用
Laravel如何配置和使用缓存?(Redis代码示例)
使用C语言编写圣诞表白程序
无锡营销型网站制作公司,无锡网选车牌流程?
如何实现建站之星域名转发设置?
进行网站优化必须要坚持的四大原则
Python高阶函数应用_函数作为参数说明【指导】
免费网站制作appp,免费制作app哪个平台好?
实例解析angularjs的filter过滤器
javascript事件捕获机制【深入分析IE和DOM中的事件模型】
js代码实现下拉菜单【推荐】
laravel怎么在请求结束后执行任务(Terminable Middleware)_laravel Terminable Middleware请求结束任务执行方法
Java遍历集合的三种方式
Laravel如何编写单元测试和功能测试?(PHPUnit示例)
如何在建站之星网店版论坛获取技术支持?
青岛网站建设如何选择本地服务器?
QQ浏览器网页版登录入口 个人中心在线进入
成都网站制作公司哪家好,四川省职工服务网是做什么用?
微信公众帐号开发教程之图文消息全攻略
JS实现鼠标移上去显示图片或微信二维码
Linux后台任务运行方法_nohup与&使用技巧【技巧】
详解jQuery停止动画——stop()方法的使用
浅述节点的创建及常见功能的实现
Edge浏览器提示“由你的组织管理”怎么解决_去除浏览器托管提示【修复】
海南网站制作公司有哪些,海口网是哪家的?
百度浏览器如何管理插件 百度浏览器插件管理方法
如何使用 jQuery 正确渲染 Instagram 风格的标签列表
如何在沈阳梯子盘古建站优化SEO排名与功能模块?
Laravel Blade组件怎么用_Laravel可复用视图组件的创建与使用
Laravel storage目录权限问题_Laravel文件写入权限设置
jQuery 常见小例汇总
Laravel的.env文件有什么用_Laravel环境变量配置与管理详解
Laravel怎么实现搜索高亮功能_Laravel结合Scout与Algolia全文检索【实战】
使用豆包 AI 辅助进行简单网页 HTML 结构设计
如何用虚拟主机快速搭建网站?详细步骤解析
网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?
php增删改查怎么学_零基础入门php数据库操作必知基础【教程】
制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?
JavaScript中如何操作剪贴板_ClipboardAPI怎么用
Laravel怎么实现支付功能_Laravel集成支付宝微信支付
java中使用zxing批量生成二维码立牌
实例解析Array和String方法
如何解决hover在ie6中的兼容性问题
高性能网站服务器部署指南:稳定运行与安全配置优化方案
如何选择PHP开源工具快速搭建网站?
网站制作报价单模板图片,小松挖机官方网站报价?
Gemini怎么用新功能实时问答_Gemini实时问答使用【步骤】
通义万相免费版怎么用_通义万相免费版使用方法详细指南【教程】


rr.Path == "/tmp/data.txt" {
// 处理特定路径的错误
}
}