英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论