恐慌:错误:*目标必须是接口或在Go中实现错误

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

panic: errors: *target must be interface or implement error in Go

问题

我正在为Go语言编写一个处理JSON反序列化错误的函数:

  1. import "github.com/pkg/errors"
  2. func parseJSONError(err error) {
  3. var uterr json.UnmarshalTypeError
  4. if errors.As(err, &uterr) {
  5. //...
  6. return
  7. }
  8. var serr json.SyntaxError
  9. if errors.As(err, &serr) {
  10. //...
  11. return
  12. }
  13. }

但是在errors.As()函数中出现了恐慌错误:panic: errors: *target must be interface or implement error

我们可以从github.com/pkg/errors文档中了解到target的含义:

  1. func As(err error, target interface{}) bool

问题在于json.UnmarshalTypeErrorjson.SyntaxError实际上都实现了error接口。我们可以从encoding/json文档中了解到这一点。所以我不知道我做错了什么。即使将uterrserr显式转换为interface{}也无法解决这个问题。

这个恐慌错误在github.com/pkg/errors和标准的errors包中都会发生。

英文:

I am making a json unmarshalling error handling function in Go:

  1. import "github.com/pkg/errors"
  2. func parseJSONError(err error) {
  3. var uterr json.UnmarshalTypeError
  4. if errors.As(err, &uterr) {
  5. //...
  6. return
  7. }
  8. var serr json.SyntaxError
  9. if errors.As(err, &serr) {
  10. //...
  11. return
  12. }
  13. }

But there is a panic in errors.As(): panic: errors: *target must be interface or implement error.

What is target we can learn from the github.com/pkg/errors documentation:

func As(err error, target interface{}) bool

The problem is that both json.UnmarshalTypeError and json.SyntaxError actually implement the error interface. We can learn it from the encoding/json documentation. So I do not have any idea what I am doing wrong. Even explicit casting uterr and serr to the interface{} does not save the situation.

The panic occurs in both github.com/pkg/errors and standard errors packages.

答案1

得分: 12

errors.As的文档说明如下:

> 如果目标不是非空指针,要么是实现了error接口的类型,要么是任何接口类型,As将会引发panic。如果err为nil,则As返回false。

因此,你需要考虑以下几点:

  1. json.UnmarshalTypeError没有实现error接口。
  2. *json.UnmarshalTypeError实现了error接口,因为它的方法Error() string具有指针接收器(文档)。
  3. 根据文档,errors.As需要一个指向实现了error接口的类型的指针,所以你需要使用**json.UnmarshalTypeError

将代码修改为:

  1. uterr := &json.UnmarshalTypeError{}
  2. if errors.As(err, &uterr) {
  3. // ...
  4. return
  5. }
英文:

The documentation of errors.As states:

> As will panic if target is not a non-nil pointer to either a type that implements error, or to any interface type. As returns false if err is nil.

So you have to consider the following:

  1. json.UnmarshalTypeError does not implement error.
  2. *json.UnmarshalTypeError does, because the method Error() string has a pointer receiver (docs)
  3. based on the documentation, errors.As wants a pointer to what implements error, so you need **json.UnmarshalTypeError

Change the code to:

  1. uterr := &json.UnmarshalTypeError{}
  2. if errors.As(err, &uterr) {
  3. // ...
  4. return
  5. }

答案2

得分: 0

你也可以简单地添加-unsafeptr标志。像这样:

  1. go vet -unsafeptr ./...
英文:

You also can simply add -unsafeptr flag. Like so:

  1. go vet -unsafeptr ./...

huangapple
  • 本文由 发表于 2021年10月5日 17:22:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/69447919.html
匿名

发表评论

匿名网友

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

确定