Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

do not define dynamic errors, use wrapped static errors instead: "XXXX" (err113) #418

Open
CarlJi opened this issue Oct 24, 2024 · 0 comments

Comments

@CarlJi
Copy link
Contributor

CarlJi commented Oct 24, 2024

这个警告提醒你不要定义动态错误,而是应该使用静态错误并通过错误包装来处理错误。

背景

在 Go 语言中,我们可以通过 fmt.Errorf 动态创建错误,尤其是带有格式化字符串的错误信息。然而,对于一些固定的错误信息,不建议每次都动态生成新的错误对象。相反,应该使用预定义的、可复用的静态错误(通常是一个包级别的 var 错误变量),并在需要时对错误进行包装或附加上下文。

原因

  1. 复用和比较:在 Go 中,通过 errors.Is 或直接比较错误值,可以轻松判断错误的类型。如果每次都通过 fmt.Errorf 动态生成错误对象,那么这些错误对象是不同的,无法直接进行比较。

  2. 性能:静态错误的内存分配只会发生一次,而动态生成的错误会在每次生成时分配新的内存,增加不必要的开销。

  3. 可读性:使用静态错误可以让代码更加简洁和可维护,因为常见的错误可以在包级别定义并复用。

示例

错误的做法(动态错误)

// 动态生成错误信息
err := fmt.Errorf("docker image is not set")

这种方式会每次生成一个新的错误对象,导致错误无法复用和比较。

正确的做法(使用静态错误)

你可以定义一个静态的错误变量,然后在需要时用它来表示特定类型的错误:

// 定义一个静态错误
var ErrDockerImageNotSet = errors.New("docker image is not set")

// 使用静态错误
if someCondition {
    return ErrDockerImageNotSet
}

这样做有几个好处:

  1. 复用ErrDockerImageNotSet 是静态定义的,可以在不同的地方复用。

  2. 比较:可以通过 errors.Is 或直接比较来判断错误类型:

    if errors.Is(err, ErrDockerImageNotSet) {
        // 处理 docker image 未设置的错误
    }

包装错误以增加上下文信息

如果你想使用静态错误并且还想在错误中附加一些上下文信息,可以使用 fmt.Errorf"%w" 语法来包装静态错误,而不是动态生成新的错误:

var ErrDockerImageNotSet = errors.New("docker image is not set")

// 包装错误并添加上下文信息
return fmt.Errorf("failed to start container: %w", ErrDockerImageNotSet)

在这个例子中,我们保留了静态错误 ErrDockerImageNotSet,并通过 %w 包装错误,保持了错误可比较的特性,同时附加了上下文信息 "failed to start container"

总结

  • fmt.Errorf("docker image is not set") 是一种动态错误的创建方式,每次都会生成新的错误对象。
  • 静态错误是通过 errors.Newvar 定义的全局错误变量,便于复用和比较。
  • 在需要提供上下文信息时,可以用 fmt.Errorf"%w" 包装静态错误,而不是直接创建新的动态错误。

因此,err113 的意思是:不要使用动态生成的错误,而应定义静态错误并在需要时进行包装

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant