在Go中处理错误
我已经和围棋一起工作了一段时间,还没有真正弄清楚我是如何处理错误的 即使是标准库也有许多不同的方法来处理错误(有些方法甚至无法在不必求助于字符串匹配的情况下检查错误) 我最近读了戴夫·切尼的博客文章。这听起来是朝着正确的方向迈出的一步,但我仍然很难真正将其付诸实践 假设我制作了一个包在Go中处理错误,go,error-handling,Go,Error Handling,我已经和围棋一起工作了一段时间,还没有真正弄清楚我是如何处理错误的 即使是标准库也有许多不同的方法来处理错误(有些方法甚至无法在不必求助于字符串匹配的情况下检查错误) 我最近读了戴夫·切尼的博客文章。这听起来是朝着正确的方向迈出的一步,但我仍然很难真正将其付诸实践 假设我制作了一个包a,它向第三方RESTAPI(例如Facebook Graph)发出请求。我希望这个包公开与API匹配的函数,比如说GetUser 调用GetUser会产生很多结果: 成功 由于请求失败(如第三方API关闭)而失败
a
,它向第三方RESTAPI(例如Facebook Graph)发出请求。我希望这个包公开与API匹配的函数,比如说GetUser
调用GetUser
会产生很多结果:
200 OK
,503服务不可用
,400错误请求
,500内部服务器错误
响应
解决这个问题的一个好的通用方法是什么,而不必包括从包
a
返回http响应代码或类似代码?我要做的是定义一些“包装错误”,以指示错误实际发生的位置。例如
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.
}
在使用了一段时间后,我没有找到一个感觉恰到好处的解决方案,我开始接受没有一个好的解决方案 我想这也可能意味着: 然而,我已经得出结论,没有单一的方法来处理错误 由于依赖性挑战带来的问题,我仍然希望避免类型断言错误,因此我引入了一种类似于链接文章中提到的
临时()bool
模式的内部()bool
行为
这至少允许我断言行为,而不必强制导入最初创建错误的包
这不是最合适的,但现在必须这样
Ainar-G的也值得一看。Dave Cheney关于错误的另一个有趣的观点。是的,请阅读John s Perayil建议的相关文章:他在这方面也做得很好,但我在发布之前阅读/观看了这些文章。之所以发布这个问题,是因为我不知道如何将它们应用于所描述的问题。Dave Cheneys博客的要点是,应该避免类型断言错误。当所有不同的可能错误都需要自己的类型时,它也会快速上升,这样调用者就可以判断如何进一步处理链上的错误。