错误处理:返回内置错误 vs 自定义类型

huangapple go评论89阅读模式
英文:

Error handling: returning build-in error vs custom type

问题

在Go的标准库中,内置的error类型用于错误处理。这篇文章使用了一些来自标准库的示例来演示Go中的错误处理工作原理。

package net

type Error interface {
    error
    Timeout() bool   // 错误是否为超时错误?
    Temporary() bool // 错误是否为临时错误?
}

if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
    time.Sleep(1e9)
    continue
}
if err != nil {
    log.Fatal(err)
}

我想知道坚持这种约定的好处是什么。如果我们返回自定义类型,例如net.Error类型,会有什么影响?

英文:

In Go's standard libraries, the built-in error is used for error handling. This post used some examples from the std libs to demonstrate how error handling works in Go.

package net

type Error interface {
    error
    Timeout() bool   // Is the error a timeout?
    Temporary() bool // Is the error temporary?
}

if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
    time.Sleep(1e9)
    continue
}
if err != nil {
    log.Fatal(err)
}

I am wondering what would be the benefits of sticking to this convention.
What if we return the custom type? e.g. net.Error type.

答案1

得分: 2

我假设你在谈论DoRequest() errorDoRequest() net.SomeSpecificError之间的区别。

以下是代码:

type CustomError struct {
}

func (CustomError) Error() string {
	return "自定义错误"
}

func DoRequest() *CustomError {
	return nil
}

func MarkTaskComplete() error {
	return nil
}

func main() {
	err := DoRequest()
	if err != nil {
		log.Fatal(err)
	}
	err = MarkTaskComplete()
	if err != nil {
		log.Fatal(err)
	}
}

这段代码无法编译通过,因为MarkTaskComplete返回的错误不能赋值给类型为*SomeError的err变量。

第二个缺点是,你不能从DoRequest返回除SomeError之外的任何其他错误。在某些情况下,这种限制可能会有一些好处,但一般情况下,使用error的方法更加灵活,特别是当你的函数调用另一个函数时。

值得阅读关于错误包装的文章:关于错误包装的文章

英文:

I assume that you are talking about the difference between DoRequest() error vs DoRequest() net.SomeSpecificError.

Following code



type CustomError struct {
}

func (CustomError) Error() string {
	return "custom error"
}

func DoRequest() *CustomError {
	return nil
}

func MarkTaskComplete() error {
	return nil
}

func main() {
	err := DoRequest()
	if err != nil {
		log.Fatal(err)
	}
	err = MarkTaskComplete()
	if err != nil {
		log.Fatal(err)
	}
}

will fail to compile because error returned by MarkTaskComplete cannot be assigned to err variable which is of type *SomeError.

Second disadvantage is that you cannot return from DoRequest any other error than SomeError. There may be a few situations where you would benefit from such a restriction, but in general in most cases the approach with error is more flexible. Especially when your function calls another one.

It is also worth to read about the errors wrapping

答案2

得分: -1

客户类型的好处,即net.Error是:

type Error interface {
    error
    Timeout() bool   // 错误是否为超时?
    Temporary() bool // 错误是否为临时错误?
}

上述代码的优点在于更具描述性。我们可以获取有关错误的更多信息,例如它是超时错误还是临时错误。

除此之外,我们还可以了解主要数据,该数据位于上述示例中的主要字段"error"中,它是一个字符串。

type error interface {
    Error() string
}
英文:

The benefits of the customer type, ie net.Error is:

    type Error interface {

    error
    Timeout() bool   // Is the error a timeout?
    Temporary() bool // Is the error temporary?
}

The above has the advantage of being more descriptive. We get more information about the error like whether it is a Timeout error or a Temporary error.

In addition to that, we also get to know the primary data which is in the primary field "error", in the above example, which is a string.

type error interface {
	Error() string
}

huangapple
  • 本文由 发表于 2021年7月16日 16:52:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/68406222.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定