跳到主要内容
版本:2.9.x(Latest)

Equal 比较方法

错误对象支持比较, Equal 方法用于完整判断两个 error 是否相同。主要通过以下方法:

// Equal reports whether current error `err` equals to error `target`.
// Please note that, in default comparison for `Error`,
// the errors are considered the same if both the `code` and `text` of them are the same.
func Equal(err, target error) bool

接口定义

如果自定义的错误数据结构需要支持比较,需要自定义的错误结构实现以下接口:

// IEqual is the interface for Equal feature.
type IEqual interface {
Error() string
Equal(target error) bool
}

通过 GoFrame 框架错误组件创建的错误对象已经实现实现了该接口,组件默认比较逻辑判断错误码和错误信息。

信息

需要注意,如果两个错误均不带错误码,并且错误信息相等,那么组件认为两个错误相等。

使用示例

func ExampleEqual() {
err1 := errors.New("permission denied")
err2 := gerror.New("permission denied")
err3 := gerror.NewCode(gcode.CodeNotAuthorized, "permission denied")
fmt.Println(gerror.Equal(err1, err2))
fmt.Println(gerror.Equal(err2, err3))

// Output:
// true
// false
}

Is 判断错误链中是否包含目标错误

  • 说明:Is 方法用于判断错误链中是否包含特定的目标错误。该方法是对 Go 标准库 errors.Is 的封装,保证了与标准库相同的性能。

  • 格式:

    Is(err, target error) bool
  • 示例:

    func ExampleIs() {
    // 创建一个特定的错误作为目标
    targetErr := gerror.New("target error")

    // 包装错误
    err1 := gerror.Wrap(targetErr, "wrap error 1")
    err2 := gerror.Wrap(err1, "wrap error 2")

    // 使用Is判断是否包含目标错误
    fmt.Println(gerror.Is(err2, targetErr))

    // 与不相关的错误进行判断
    otherErr := gerror.New("other error")
    fmt.Println(gerror.Is(err2, otherErr))

    // Output:
    // true
    // false
    }

As 将错误转换为特定类型

  • 说明:As 方法用于将错误链中的错误转换为特定类型。它会在错误链中查找第一个与目标类型匹配的错误,如果找到,则将其转换为目标类型并返回 true。该方法是对 Go 标准库 errors.As 的封装,保证了与标准库相同的性能。

  • 格式:

    As(err error, target any) bool
  • 示例:

    // 自定义错误类型
    type MyError struct {
    Message string
    Code int
    }

    // 实现error接口
    func (e *MyError) Error() string {
    return fmt.Sprintf("code: %d, message: %s", e.Code, e.Message)
    }

    func ExampleAs() {
    // 创建一个自定义错误
    originalErr := &MyError{Message: "database connection failed", Code: 500}

    // 包装错误
    err := gerror.Wrap(originalErr, "operation failed")

    // 尝试将错误转换为MyError类型
    var myErr *MyError
    if gerror.As(err, &myErr) {
    fmt.Println("Error code:", myErr.Code)
    fmt.Println("Error message:", myErr.Message)
    }

    // 尝试转换为不匹配的类型
    type OtherError struct{}
    var otherErr *OtherError
    fmt.Println(gerror.As(err, &otherErr))

    // Output:
    // Error code: 500
    // Error message: database connection failed
    // false
    }

As 方法在以下场景中特别有用:

  1. 类型断言:当您需要从错误链中提取特定类型的错误信息时。

  2. 错误处理:根据错误类型执行不同的处理逻辑。

  3. 自定义错误恢复:当需要从错误中提取特定信息来实现错误恢复机制时。

下面是一个实际应用的例子:

package main

import (
"fmt"

"github.com/gogf/gf/v2/errors/gerror"
)

// 数据库错误
type DBError struct {
Table string
Message string
}

func (e *DBError) Error() string {
return fmt.Sprintf("database error on table '%s': %s", e.Table, e.Message)
}

// 认证错误
type AuthError struct {
Username string
Message string
}

func (e *AuthError) Error() string {
return fmt.Sprintf("authentication error for user '%s': %s", e.Username, e.Message)
}

// 模拟数据库操作
func queryDatabase() error {
return gerror.Wrap(&DBError{
Table: "users",
Message: "connection timeout",
}, "database query failed")
}

// 模拟用户认证
func authenticateUser() error {
return gerror.Wrap(&AuthError{
Username: "john_doe",
Message: "invalid password",
}, "authentication failed")
}

// 处理不同类型的错误
func handleError(err error) {
// 尝试将错误转换为数据库错误
var dbErr *DBError
if gerror.As(err, &dbErr) {
fmt.Println("Database error detected:")
fmt.Println(" Table:", dbErr.Table)
fmt.Println(" Message:", dbErr.Message)
fmt.Println(" Recommended action: Check database connection and retry")
return
}

// 尝试将错误转换为认证错误
var authErr *AuthError
if gerror.As(err, &authErr) {
fmt.Println("Authentication error detected:")
fmt.Println(" Username:", authErr.Username)
fmt.Println(" Message:", authErr.Message)
fmt.Println(" Recommended action: Verify credentials and try again")
return
}

// 其他错误类型
fmt.Println("Unknown error:", err.Error())
}

func main() {
// 模拟数据库错误
err1 := queryDatabase()
handleError(err1)

fmt.Println()

// 模拟认证错误
err2 := authenticateUser()
handleError(err2)
}

运行结果:

Database error detected:
Table: users
Message: connection timeout
Recommended action: Check database connection and retry

Authentication error detected:
Username: john_doe
Message: invalid password
Recommended action: Verify credentials and try again
Ask me