Go – errors.As() 不识别类型

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

Go - errors.As() not recognising type

问题

我正在使用一个辅助函数来解码JSON。它返回一个自定义的错误类型,其中包含无法解析JSON的原因和我应该返回的HTTP代码。

package dto

type MalformedRequestError struct {
	Status  int
	Message string
}

func (mr *MalformedRequestError) Error() string {
	return mr.Message
}

在解码请求体时,我首先要做的一件事是检查客户端是否正确设置了Content-Type头。

package webhandlers

func decodeJSONBody(w http.ResponseWriter, r *http.Request, dst interface{}) error {
	if r.Header.Get("Content-Type") != "" {
		value, _ := header.ParseValueAndParams(r.Header, "Content-Type")
		if value != "application/json" {
			Message := "Content-Type header is not application/json"
			return &dto.MalformedRequestError{Status: http.StatusUnsupportedMediaType, Message: Message}
		}
	}
    ... etc ...

我尝试使用errors.As()来检查函数是否返回了我的自定义错误,但它不起作用。

package webhandlers

func (i *InternalTokenHandler) Post(w http.ResponseWriter, r *http.Request) {
	type postRequest struct {
		Google_id_token string
	}
	// 解析请求数据
	var parsedRequest postRequest
	err := decodeJSONBody(w, r, &parsedRequest)
	if err != nil {
        // 输出 *dto.MalformedRequestError
		fmt.Println(fmt.Sprintf("%T", err))
		var mr *dto.MalformedRequestError
		if errors.As(err, &mr) {
			http.Error(w, mr.Message, mr.Status)
		} else {
			log.Println(err)
			http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		}
		return
	}
    .... 更多代码 ...

我已经检查了错误的类型是*dto.MalformedRequestError,但是我的代码总是进入else块并返回通用的500服务器错误。

我漏掉了什么?为什么errors.As()无法识别错误类型?

英文:

I am using a helper function to decode JSON. It returns a custom error type that is populated with the reason why it could not parse the JSON and the HTTP code I should return.

package dto

type MalformedRequestError struct {
	Status  int
	Message string
}

func (mr *MalformedRequestError) Error() string {
	return mr.Message
}

One of the first things I do when decoding the body is to check that the client has correctly set the Content-Type header.

package webhandlers

func decodeJSONBody(w http.ResponseWriter, r *http.Request, dst interface{}) error {
	if r.Header.Get("Content-Type") != "" {
		value, _ := header.ParseValueAndParams(r.Header, "Content-Type")
		if value != "application/json" {
			Message := "Content-Type header is not application/json"
			return &dto.MalformedRequestError{Status: http.StatusUnsupportedMediaType, Message: Message}
		}
	}
    ... etc ...

I try to use errors.As() to check that the function is returning my custom error, but it is not working.

package webhandlers

func (i *InternalTokenHandler) Post(w http.ResponseWriter, r *http.Request) {
	type postRequest struct {
		Google_id_token string
	}
	// parse request data
	var parsedRequest postRequest
	err := decodeJSONBody(w, r, &parsedRequest)
	if err != nil {
        // outputs *dto.MalformedRequestError
		fmt.Println(fmt.Sprintf("%T", err))
		var mr *dto.MalformedRequestError
		if errors.As(err, &mr) {
			http.Error(w, mr.Message, mr.Status)
		} else {
			log.Println(err)
			http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		}
		return
	}
    .... more code ...

I have checked that the type of the error is *dto.MalformedRequestError, but my code is always reaching the else block and returning the generic server 500 error.

What am I missing - why is errors.As() not recognizing the error type?

答案1

得分: 3

这个链接有效:https://go.dev/play/p/CWe9mVp7QOz。

如果你的代码真的失败了,我能想到的唯一原因是decodeJSONBody使用的dto包与InternalTokenHandler.Post使用的dto包不同,因此两个错误类型会不同。

请注意,即使是同一个包的不同版本也被视为不同的包,其中声明的类型并不是相同的

英文:

This works: https://go.dev/play/p/CWe9mVp7QOz.

The only reason I can think of that would cause your code to fail, if it really does fail, is that the dto package used by decodeJSONBody is not the same as the dto package used by InternalTokenHandler.Post, hence the two error types would be different.

Note that even different versions of the same package count as different packages and types declared in those are not identical.

huangapple
  • 本文由 发表于 2022年3月26日 18:15:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/71627129.html
匿名

发表评论

匿名网友

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

确定