我现在和Go一起工作了一段时间,还没有确定我如何处理错误。
即使是标准库也有许多不同的方法来处理错误(有些甚至无法检查错误而不必求助于字符串匹配)。
我最近阅读了Dave Cheney撰写的博文Inspecting Errors。这听起来像是朝着正确方向迈出的一步,但我仍然很难真正实现它。
假设我已经创建了一个包a
来向第三方REST API(例如Facebook Graph)发出请求。我希望这个软件包能够公开与API相匹配的函数 - 比方说GetUser
。
调用GetUser
可以产生许多结果:
在第二种情况下,断言行为错误非常有效。然而,它在区分第三和第四种情况方面做得不够。
我目前的用例是实现我自己的REST API,它使用第一个包。在这种情况下,我希望能够分别回复{{1}},200 OK
,503 Service Unavailable
,400 Bad Request
个回复。
解决此问题的一般方法是什么,而不必在包500 Internal Server Error
中包含返回的http响应代码或类似内容?
答案 0 :(得分:4)
我要做的是定义一些“包装错误”来表示错误实际发生的位置。 E.g。
type SerializationError struct { Error error }
func (err SerializationError) Error() string { return err.Error.Error() }
type HTTPError struct { Error error }
// ...
然后在您的API客户端的代码中:
b, err := json.Marshal(v)
if err != nil {
return nil, SerializationError{err}
}
// ...
resp, err := client.Post(url, ct, body)
if err != nil {
return nil, HTTPError{err}
}
然后,你可以这样做:
err := client.GetUser(id)
switch err.(type) {
case SerializationError:
// respond with 400
case HTTPError:
// respond with 500
// etc.
}
答案 1 :(得分:0)
在使用了一段时间之后,没有更接近一个感觉恰到好处的解决方案,我正在接受这方面没有一个好的单一解决方案。
我想这可能也是Dave Cheney的含义:
但是,我得出结论,没有一种方法可以处理错误。
由于我仍然希望避免由于依赖性挑战而导致类型声明错误,因此我最终引入了类似于链接文章中提到的Internal() bool
模式的Temporary() bool
行为。
这至少允许我断言行为而不必强制导入最初创建错误的包。
这不是最合适的,但现在必须要做。
Ainar-G的answer值得一看。