错误处理的经验
错误的处理是一个服务必不可缺的环节。经过一些实践和积累,对错误处理进行阶段性的总结。
在平时的业务开发中,我们可以认为http状态码不为2xx系列的,都可以认为是请求错误, 并伴随响应的错误信息。常用做法都是通过 code、message 两个字段来进行业务处理结果描述,并且希望能够以json响应体来进行响应。
一、对于Http状态码的规范:
正确统一返回http状态码为200
预定义错误(业务性错误)统一返回http状态码为400
其他(主要是500)为预期之外的异常。
结构体中,正确为统一一套结构体(业务返回)。
预定义错误和未定义错误为
{
"code":10001,
"message":"用户未找到"
}
或者
{
"reason":"USER_NOT_FOUND",
"message":"用户未找到"
}
使用code在约定上会规范一些,更好统计。使用reason会更清晰一些,见名知意。
二、这样做的好处:
充分利用httpcode,不一层一层地包裹业务内容,只需要在最外层判断httpcode即可。规范错误处理,在http状态码为非200时,客户端逻辑可以统一编码处理。后端不需要返回细节的异常信息,如某个字段不为空。只需返回大范围上的异常信息,如数据校验不通过。后端统一异常处理,异常抛出,程序会自动捕获,客户端可以抛出用户友好的提示。
三、不一样的意见
有的开发者认为,只要是预期内的错误,比如参数错误,都是可以用200返回的,然后在内部用isfailed来进行判断。
我反对: http状态码是状态码,而不是错误码,是可以完全利用起来的。业务正确错误一把梭,这里httpcode还有什么作用呢?keep it simple。
目前国内的大小厂、第三方,都是统一返回200的,或许是出于一些业务考虑,可行,但并不一定最优。
四、业界主流的做法
apple
https://appleid.apple.com/auth/token
http 400
{
"error": "invalid_client"
}
Facebook / Meta
https://graph.facebook.com/v2.9/me?fields=id%2Cname%2Cpicture%2C%20picture&
http 400
{
"error": {
"message": "An active access token must be used to query information about the current user.",
"type": "OAuthException",
"code": 2500,
"fbtrace_id": "A02VYHGCkrFVSmECEpFKmfq"
}
}
https://api.twitter.com/1.1/statuses/mentions_timeline.json
http 400
{
"errors": [
{
"code": 215,
"message": "Bad Authentication data."
}
]
}
国内主流
微信
https://api.weixin.qq.com/sns/jscode2session?appid=a4d4568079&secret=cb9eae93d063961050bf1a319a&js_code=041Kog0w3XC5EWa3w34Brpi3Kog0b&grant_type=authorization_code
http 200
{
"errcode": 40029,
"errmsg": "invalid code, rid: 63245661-33bd370a-2f5d2f67"
}
有赞
https://open.youzanyun.com/auth/token
http 200
{
"success": false,
"code": 1103,
"data": null,
"message": "未授权或者已经取消授权"
}
百度
https://spapi.baidu.com/oauth/jscode2sessionkey
http 200
{
"errno": 1104,
"error": "invalid code , expired or revoked",
"error_description": "invalid code , expired or revoked"
}
最简洁的是苹果的,只有一个error字段去描述错误信息。
我相信每一个开发人员对错误处理都有自己的理解,希望本篇对你有所启发。
欢迎留言讨论