• Golang 中的 errors 包详解:返回自定义 error 类型


    之前的文章《Golang 中的 errors 包详解》详细讲解了 errors 包的主要类型和函数,以及它们的使用方法。本文结合之前讲解的知识,来讲解一下根据自己或团队的项目要求如何返回自定义的 error 类型。

    为什么需要自定义 error 类型?

    在日常开发中,返回自定义 error 类型是一种很常见的做法,因为很多场景下标准库 errors 包中的 error 类型并不能满足需求。例如开发 web 项目时,常见的返回结构可能如下:

    {"code":xxx, "data":yyy,"msg":"zzz"}

    code 为状态码,data 为接口返回的业务数据,msg 为错误信息。针对这种响应结构,一般做法是调用处理业务逻辑的函数或方法,返回业务数据和 error,然后在 api 层拼装成这种结构。所以 error 对象至少要包含状态码 code 和错误信息 msg,这时候就需要实现自己的 error 类型了。

    如何实现自定义 error 类型?

    在 Golang 中,可以通过创建一个实现了 error 接口(该接口仅包含一个 Error 方法)的结构体来返回自定义的 error 类型。自定义的 error 类型可以包含自己定义的字段和方法,以提供更多的错误信息和上下文信息。看一个示例来展示如何创建和返回自定义 error 类型:

    1. package main
    2. import (
    3. "errors"
    4. "fmt"
    5. )
    6. // 自定义的错误类型
    7. type MyError struct {
    8. code int64
    9. msg string
    10. }
    11. // 实现error接口的Error方法
    12. func (e MyError) Error() string {
    13. return fmt.Sprintf("Error: [%d] %s", e.code, e.msg)
    14. }
    15. func (e MyError) Code() int64 {
    16. return e.code
    17. }
    18. func (e MyError) Msg() string {
    19. return e.msg
    20. }
    21. // 函数示例,返回自定义error类型
    22. func doSomething() error {
    23. err := MyError{
    24. code: 500,
    25. msg: "Something went wrong",
    26. }
    27. return err
    28. }
    29. func main() {
    30. err := doSomething()
    31. if err != nil {
    32. fmt.Println(err)
    33. }
    34. // 比较自定义error类型
    35. myErr := MyError{
    36. code: 500,
    37. msg: "Something went wrong",
    38. }
    39. equal := errors.Is(err, myErr)
    40. fmt.Println(equal) // true
    41. }

    在上述示例中,首先定义了一个自定义的 MyError 类型,包含 code 和 msg 两个字段,然后实现 error 接口要求的 Error 方法。

    接下来再看一个结合 gin 框架的具体使用示例,简单示例代码如下:

    1. package main
    2. import (
    3. "errors"
    4. "fmt"
    5. "github.com/gin-gonic/gin"
    6. "net/http"
    7. )
    8. // 自定义的错误类型
    9. type MyError struct {
    10. code int64
    11. msg string
    12. }
    13. func NewError(code int64, msg string) MyError {
    14. return MyError{
    15. code: code,
    16. msg: msg,
    17. }
    18. }
    19. // 实现error接口的Error方法
    20. func (e MyError) Error() string {
    21. return fmt.Sprintf("Error: [%d] %s", e.code, e.msg)
    22. }
    23. func (e MyError) GetCode() int64 {
    24. return e.code
    25. }
    26. func (e MyError) GetMsg() string {
    27. return e.msg
    28. }
    29. // 函数示例,返回自定义error类型
    30. func doSomething() error {
    31. err := MyError{
    32. code: 500,
    33. msg: "Something went wrong",
    34. }
    35. return err
    36. }
    37. func FromError(err error) MyError {
    38. if err == nil {
    39. return NewError(1, "")
    40. }
    41. if !errors.As(err, &MyError{}) {
    42. return NewError(-1, "")
    43. }
    44. return err.(MyError)
    45. }
    46. func TestHandler(c *gin.Context) {
    47. err := Logic()
    48. if err != nil {
    49. e := FromError(err)
    50. c.JSON(http.StatusOK, gin.H{"code": e.GetCode(), "data": nil, "msg": e.GetMsg()})
    51. return
    52. }
    53. c.JSON(http.StatusOK, gin.H{"code": 1, "data": nil, "msg": ""})
    54. }
    55. func Logic() error {
    56. return NewError(-1, "something went wrong")
    57. }
    58. func main() {
    59. r := gin.New()
    60. r.GET("/test", TestHandler)
    61. r.Run(":8080")
    62. }

    小结

    通过返回自定义的 error 类型,可以提供更多的错误信息和上下文信息,使错误处理更加灵活和准确,可以根据自己的实际需求和应用场景创建自定义错误类型。

  • 相关阅读:
    Mysql_13 事务
    股票交易sdk接口源码分享
    Python NLP教程之知识图谱,从文本构建知识,实现从文本或在线文章中提取知识库的管道(教程含源码)
    报错:HikariPool-1 - Exception during pool initialization.
    HDLbits exercises 2 (MODULES节选题)
    项目实战接口开发SpringBoot
    AT32F415 修改时钟和晶振方法(原创)
    史上最强C语言教程----万字初识C语言
    记一次百万行WPF项目代码的重构记录
    ReadWriteLock(读写锁)和阻塞队列BlockingQueue与同步队列SynchronousQueue
  • 原文地址:https://blog.csdn.net/luduoyuan/article/details/132724281