错误码与抛出异常,哪个才是最佳实践呢?

2016-09-15 13:18:20 +08:00
 miao1007

比较纠结的问题,当调用某些不可靠的操作时,一般会用 tryCatch 将它包住。不过返回的结果的表示就有多种表示方法了,具体如下:

错误码风格的设计:

try{
  //some Exception
  return msg("0","success!",resp);
} catch(ChildException ce){
  return errorMsg("1","call {xxService} failed");
}

返回空白数据的设计:

try{
  //some Exception
  return msg("0","success!",resp);
} catch(ChildException ce){
  return msg("0","success!",Collections.emptyList());
}

返回 null 的设计:

try{
  //some Exception
  return msg("0","success!",resp);
} catch(ChildException ce){
  return null;
}

抛出异常的设计:

try{
  //some Exception
  return msg("0","success!",resp);
} catch(ChildException ce){
  throw ce;
}

Stack Overflow中的回答更趋向于 Exception ,各位在实际开发中,一般采用哪种方法呢?

4485 次点击
所在节点    Java
12 条回复
tchekai704
2016-09-15 13:44:43 +08:00
同关注这个问题
neoblackcap
2016-09-15 13:45:54 +08:00
异常,我更倾向于使用了类型系统的东西
ovear
2016-09-15 13:47:22 +08:00
Java 是强制异常处理机制,如果真的是错误,意味着会影响到业务。。那么要求强制处理会比较妥当,不然偶尔脑抽的时候忘记处理,就 GG 了
palmers
2016-09-15 13:51:56 +08:00
我觉得应该结合业务需要,如果这个是致命的,应该抛出异常,强制处理; 如果后续业务可以继续流转则抛出运行时异常或者返回消息。
CFO
2016-09-15 15:08:28 +08:00
我遵循的大概原则是 会让开发感受到的 就抛出 会让用户感受到的 就处理掉
liuxu
2016-09-15 15:09:23 +08:00
有这么一个登陆的例子。

首先后台,根据用户输入的用户名密码,返回不同的状态值:
登陆成功:
{
"state":"1",
"data":[.....]
}
登陆失败:
{
"state":"0",
"data":null
}
这里登陆状态明显不需要因为数据库没查到值就 try 处理。

但下面就需要了,当用 ajax 调用上面的接口,因为在开发时,由于缓存系统的原因,有时候 js 中处理 data 的函数还是老版(资源文件缓存不更新,解决办法是在链接后面添加"?随机数"或去缓存管理中心刷新此 js),和新的 php 接口给的 data 数量不一致,会导致 js 执行失败(如果是 jquery ,它会 try 处理,无需担心此问题)。此时 js 执行中断,导致后面显示 data 数据到页面无法执行。其行为就是,用户输入了正确的用户名和密码,返回的 state 也为 1 ,但是因为 data 不一致,导致 js 失败,从而页面依然还是未登录状态,但实际上后台已经登陆成功, session 也是有效的。

为了防止以上情况,所以用 try 包住 data 处理的代码,然后不管是否执行成功,都在最后的 default 中执行显示状态框到页面上。状态框默认信息为“读取中...”,然后 data 处理的代码就是将 data 的值替换掉“读取中...”。

以上解决方案在我公司的网站上应用了,很好的解决了客服那边电话被打爆了的情况。
liuxu
2016-09-15 15:10:17 +08:00
这个和语言无关, java 也应该是通用的。
lightening
2016-09-15 16:27:24 +08:00
不可预测的异常抛出,可预测的异常处理掉。
qiukun
2016-09-15 16:38:51 +08:00
Shura
2016-09-16 08:44:58 +08:00
这让我想起了之前 bind 的一个 bug ,传入一个异常的数据包就会导致其自动退出。但是如果 bind 继续运行其实不会有什么问题。
jimzhong
2016-09-16 09:04:38 +08:00
@lightening +1 , The Practice of Programming 里面也有类似说法。
johnj
2016-09-16 10:17:42 +08:00
本层能处理的处理掉 不能处理的抛出
服务性质的层抛出 业务性质的层处理掉
面向程序员的层抛出 面向客户的层处理掉

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/306433

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX