把 throw error 当做 goto 使用是一个好的实践吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
FrankFang128

把 throw error 当做 goto 使用是一个好的实践吗?

  •  
  •   FrankFang128 2018 年 5 月 9 日 3591 次点击
    这是一个创建于 2904 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近我在做后台权限检验的时候有如下需求:

    1. 如果发现用户不满足条件 A,就返回响应 A',并停止后面的渲染
    2. 如果发现用户不满足条件 B,就返回响应 B',并停止后面的渲染
    3. 其他情况正常渲染资源详情

    由于要在很多接口里做类似的判断,所以我不太可能在每个接口里写 if...else。

    目前我的做法是在这些接口里调用一个 before_action (函数)

    如果 before_action 发现用户不满足条件,就抛出一个错误。

    然后在较高层面捕获这个错误,发送对应的响应 A' 或 B',同时由于 before_action 报错了,所以正常渲染逻辑就不会执行了。

    也就是说我在把 throw error 当做 goto 在使用:结束当前子程序,直接去执行另一段程序。

    大家平时也会这么写吗?

    14 条回复    2018-05-09 15:19:53 +08:00
    wellCh4n
        1
    wellCh4n  
       2018 年 5 月 9 日
    摘自 阿里巴巴 Java 开发手册 第七章第四条
    ```
    [推荐] 表达异常的分支时,少用 if-else 方式,这种方式可以改写成:
    if (condition) { ...
    return obj; }
    // 接着写 else 的业务逻辑代码;
    说明:如果非得使用 if()...else if()...else...方式表达逻辑, [强制] 避免后续代码维
    护困难,请勿超过 3 层。
    ```
    此外,我司(技术栈 Java )在开发的时候校验参数条件经常使用 `断言`
    FrankFang128
        2
    FrankFang128  
    OP
       2018 年 5 月 9 日
    这么多地方写一样的 if ... else 会很烦吧
    @wellCh4n 用断言然后不满足情况就报错么
    ss098
        3
    ss098  
       2018 年 5 月 9 日 via Android
    可以考虑用 middle action 来解决?我一直是这样做权限检查的。
    FrankFang128
        4
    FrankFang128  
    OP
       2018 年 5 月 9 日
    @ss098 middle action 阻止后面的渲染是怎么做的? 回调吗
    ss098
        5
    ss098  
       2018 年 5 月 9 日 via Android
    @FrankFang128 https://laravel-china.org/docs/laravel/5.6/middleware

    Laravel 中间件的文档,可以看里面的例子理解下。

    就是如果判断不通过,就返回需要返回的内容。判断通过,就调用下一个函数,返回这个函数的值。
    dcoder
        6
    dcoder  
       2018 年 5 月 9 日
    @FrankFang128
    我一直觉得 '异常' 基本就是个 goto 啊, 目的之一就是为了减少复杂的 if-else. 难道这个理解不对么?
    billlee
        7
    billlee  
       2018 年 5 月 9 日
    这个就是异常的基本用法啊,在底层发现错误,高层统一处理
    zjsxwc
        8
    zjsxwc  
       2018 年 5 月 9 日
    当然用抛异常了,更通用点,可以写一个正常无鉴权的类 CA 和一个专门鉴权的通用类 CB,CB 对象 IB1 持有这个无鉴权对象 IA1,IB1 就是对 IA1 的增强版了,然后注入替换 IA1 就行,以后有更多的类似 CA 这种类时都可以用一个 CB 对象注入替换,这样写的代码好处是完全没有副作用,**不需要更改原来任何的代码**
    wjpdev
        9
    wjpdev  
       2018 年 5 月 9 日
    AOP
    puritania
        10
    puritania  
       2018 年 5 月 9 日 via iPhone
    个人更喜欢抛异常一点,在最外层做好 catch 就好,无数的方法调用都可以抛出异常而不是各种 return 判断
    SakuraKuma
        11
    SakuraKuma  
       2018 年 5 月 9 日
    个人也是抛异常,外面 catch 就好了。
    lihongjie0209
        12
    lihongjie0209  
       2018 年 5 月 9 日
    可以使用 aop 在所有请求外面代理一下, 不满足权限的都不会进入业务代码.
    这里也不会涉及任何的异常, 只是把所有的 if 检查放到 aop 中而已
    xiaoshenke
        13
    xiaoshenke  
       2018 年 5 月 9 日
    只有我一个人是在外面套一层 while(True),然后 break 么。。。
    scmod
        14
    scmod  
       2018 年 5 月 9 日
    这种抛异常挺正常啊,如果这个异常只是为了当个 goto 一样的东西的话建议楼主自定义异常,重写 fillInStackTrace 返回 null 就行了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5495 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 62ms UTC 05:47 PVG 13:47 a href="/worldclock#lax">LAX 22:47 JFK 01:47
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86