V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
miao1007
V2EX  ›  Java

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

  •  
  •   miao1007 ·
    miao1007 · 2016-09-15 13:18:20 +08:00 · 4468 次点击
    这是一个创建于 2785 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比较纠结的问题,当调用某些不可靠的操作时,一般会用 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 ,各位在实际开发中,一般采用哪种方法呢?

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

    首先后台,根据用户输入的用户名密码,返回不同的状态值:
    登陆成功:
    {
    "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
        7
    liuxu  
       2016-09-15 15:10:17 +08:00
    这个和语言无关, java 也应该是通用的。
    lightening
        8
    lightening  
       2016-09-15 16:27:24 +08:00
    不可预测的异常抛出,可预测的异常处理掉。
    Shura
        10
    Shura  
       2016-09-16 08:44:58 +08:00 via Android
    这让我想起了之前 bind 的一个 bug ,传入一个异常的数据包就会导致其自动退出。但是如果 bind 继续运行其实不会有什么问题。
    jimzhong
        11
    jimzhong  
       2016-09-16 09:04:38 +08:00
    @lightening +1 , The Practice of Programming 里面也有类似说法。
    johnj
        12
    johnj  
       2016-09-16 10:17:42 +08:00   ❤️ 1
    本层能处理的处理掉 不能处理的抛出
    服务性质的层抛出 业务性质的层处理掉
    面向程序员的层抛出 面向客户的层处理掉
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   818 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 22:16 · PVG 06:16 · LAX 15:16 · JFK 18:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.