所有的示例都是围绕着这个 demo 来讨论, 这个 demo 的大意就想创建一个用户,但是在创建用户之前需要检测一下用户的手机号是否存在
func CreateUser(mobile string) (*User, error) {
exists, err := mobileExists(mobile)
if err != nil {
return nil, err
}
if exists {
return nil, fmt.Errorf("User already exists")
}
// ...
}
第一个问题是在 return error 的时候要不要写入日志,代码要不要变成这样
func CreateUser(mobile string) (*User, error) {
exists, err := mobileExists(mobile)
if err != nil {
logger.Errorf("can not close the response", err)
return nil, err
}
if exists {
return nil, fmt.Errorf("User already exists")
}
// ...
}
我得想法总的来说是这样的,要不要把 error 写入日志这个事应该是调用的人来负责,而不是被调用的人来负责,我得想法总的来说 是要么写入日志要么返回错误,而不应该两件事情都干。不知道这个想法对不对?日志的返回这里要不要使用 fmt.Errorf("CreateUser Fail: %w", err) 再返回,扩展开就是什么情况下需要包裹一下
第二个点是关于错误如何和 HTTP 的 Status 关联起来
比如第一个 exists, err := mobileExists(mobile) 这里返回的 err 我希望是一个 HTTP 500 的错误信息,这个点我希望的是非业务层的错误返回 500 比如数据连接失败,redis 连接失败。而且 HTTP 的错误信息还需要返回自己定义的信息。
但是 if exists { return nil, fmt.Errorf("User already exists") } 这个我却希望是一个 HTTP 400 的错误。这个只是举例的这一个 error ,但是内部单纯的业务层面的就有几十个 error 。但是我发现好像不知道怎么做到这一点。