使用类型断言来处理错误是否是错误的?

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

is it wrong to use type assertion for error handling?

问题

我想知道为什么在Go语言中,为什么不常用/推荐使用switch + 类型断言的方式来处理错误。这种方式有什么问题,或者是社区对此不关心吗?

例如下面的代码:

if err != nil {
	if errors.As(err, &QueryErr{}) {
		log.Println("query error:", err)
		return http.StatusInternalServerError
	} else if errors.As(err, &QueryDataExtractionErr{}) {
		return http.StatusNotFound
	} else {
		log.Println(err.Error())
		return http.StatusInternalServerError
	}
}

可以改写为:

if err != nil {
    switch err.(type) {
	case QueryErr:
		log.Println("query error:", err)
		return http.StatusInternalServerError
	case QueryDataExtractionErr:
		return http.StatusNotFound
	default:
		log.Println(err.Error())
		return http.StatusInternalServerError
    }
}
英文:

i was wondering why isn't switch + type assertion style error handling more used/recommended in golang. is there anything wrong with it or the community just doesn't care about it ?

for example the code below :

if err != nil {
	if errors.As(err, &QueryErr{}) {
		log.Println("query error : ", err)
		return http.StatusInternalServerError
	} else if errors.As(err, &QueryDataExtractionErr{}) {
		return http.StatusNotFound
	} else {
		log.Println(err.Error())
		return http.StatusInternalServerError
	}
}

could be written as :

if err != nil {
    switch err.(type) {
	case QueryErr:
		log.Println("query error : ", err)
		return http.StatusInternalServerError
	case QueryDataExtractionErr:
		return http.StatusNotFound
	default:
		log.Println(err.Error())
		return http.StatusInternalServerError
    }
}

答案1

得分: 4

类型切换在技术上是正确的。然而,带有错误的类型切换会错误地解释封装的错误。例如:

err := io.EOF
err1 := fmt.Errorf("Unexpected error: %w", err)

在上面的代码中,err1.(io.EOF) 将失败,但 errors.Is(err1, io.EOF) 不会失败。

因此,你应该使用 errors.Iserrors.As 来测试你手头的错误是否封装了你要查找的错误。

英文:

The type-switch is technically correct. However, the type-swich with errors will misinterpret wrapped errors. For instance:

err:=io.EOF
err1 := fmt.Errorf("Unexpected error: %w",err)

In the above, err1.(io.EOF) will fail, but errors.Is(err1,io.EOF) will not.

So you should use errors.Is and errors.As to test whether the error you have at hand wraps the error you are looking for.

huangapple
  • 本文由 发表于 2023年3月20日 01:52:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/75783918.html
匿名

发表评论

匿名网友

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

确定