You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Go标准库errors.As无法解包自定义错误类型的问题

问题原因分析

你的代码存在两个关键问题:

  1. 类型不匹配:retError()返回的是*myError指针类型的错误,但main中声明的目标变量m是myError值类型。errors.As会严格匹配错误的动态类型,因此无法将*myError赋值给myError类型的目标,导致匹配失败。
  2. 未实现错误解包接口:你的myError结构体没有实现Unwrap() error方法,即使匹配到myError实例,也无法通过errors.As递归解开它包装的底层错误。

修正后的代码

以下是同时解决两个问题的完整代码:

package main

import (
    "errors"
    "fmt"
)

type myError struct {
    err error
}

func (m myError) Error() string {
    return fmt.Sprintf("my error: %s", m.err)
}

// 实现Unwrap方法,支持错误链解包
func (m myError) Unwrap() error {
    return m.err
}

func retError() error {
    return &myError{errors.New("wrapped")}
}

func main() {
    var m *myError // 将目标变量改为指针类型
    err := retError()
    if errors.As(err, &m) {
        fmt.Println("unwrapped", m.err)
        // 可选:进一步解包底层错误
        var wrappedErr *errors.errorString
        if errors.As(err, &wrappedErr) {
            fmt.Println("底层原始错误:", wrappedErr)
        }
    } else {
        fmt.Println(err)
    }
}

关键说明

  • 类型匹配调整:当错误是指针类型(*myError)时,errors.As的目标参数需要是指向该指针的指针(即**myError),因此声明var m *myError并传入&m才能匹配成功。
  • Unwrap方法的作用:实现该方法后,errors.As可以递归遍历错误链,不仅能匹配myError本身,还能直接定位到它包装的底层错误。如果仅需获取myError实例,可省略Unwrap方法,但你的需求是提取底层错误,因此必须实现它。

内容的提问来源于stack exchange,提问作者renbou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 06:45:35