V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
zhangqilin
V2EX  ›  程序员

后端接口是否用 try/except 好?还是不用好?

  •  
  •   zhangqilin · 2018-10-29 14:06:19 +08:00 · 2905 次点击
    这是一个创建于 2247 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在看后台日志,一堆 try/except 后打印出的错误信息 但有这么一堆错误信息还是排查不出问题 我自己维护的项目中 try/except 很少,因为我觉得运用大量的 try 只是掩盖了问题,而不是去解决问题

    而实际上我在维护别人项目的时候,比如一个接口的代码为:

    1. 获取参数
    2. 业务逻辑(一大块 try/except,出错了就返回 fail )
    3. 返回 ok/fail

    这样在服务器日志里看到有打印出来的错误信息,很不爽,想去解决 但又找不到问题出在哪儿,因为报的也不多 可能是强迫症吧

    因为这是我第一个公司,所以想问一下 V2EX 的同志们

    究竟是大片的 try/except 好?还是几乎不写 try/except 好

    或者说

    try/except 究竟应该在哪些场合应用?

    15 条回复    2018-10-29 18:02:06 +08:00
    cy97cool
        1
    cy97cool  
       2018-10-29 14:31:08 +08:00
    赶紧用 sentry

    只有异常是期待中的 才需要用 except 否则就丢给上一层调用者处理
    不该处理的异常就别处理 并非 try-except 写的多就程序更健壮更靠谱

    出错了就返回 fail 即使不用 sentry 至少也应该同时记录一下 traceback.print_exc()
    janus77
        2
    janus77  
       2018-10-29 14:32:52 +08:00
    不是越多越好,但是该用的地方肯定要用的啊
    p2pCoder
        3
    p2pCoder  
       2018-10-29 14:35:22 +08:00
    你还不会打日志,这是最大的问题
    很多地方 try except 是必要的,这是程序健壮性必须的
    后端接口,不要直接把 exception 直接抛给 接口调用方,无论调用方是 web 前端,还是其他服务
    调用方并不关心你究竟又啥异常

    楼主还是多向公司有经验的问问,日志打不好,排查线上问题是很老火的
    owenliang
        4
    owenliang  
       2018-10-29 14:54:42 +08:00
    我觉得框架捕获就可以,业务代码别处理那么多异常。

    框架捕获了该打日志打日志,该采集采集,能追查能报警就很好。
    TheWalkingDead
        5
    TheWalkingDead  
       2018-10-29 15:01:48 +08:00
    这是打日志的问题,即使用了 try except,也可以完整的打印出异常栈
    welkinzh
        6
    welkinzh  
       2018-10-29 15:03:11 +08:00
    是日志没反映出问题,不能怪 try/except
    xuanbg
        7
    xuanbg  
       2018-10-29 15:26:47 +08:00
    异常处理里面没有业务逻辑的话,还是交给框架去捕获好了。
    TommyLemon
        8
    TommyLemon  
       2018-10-29 15:43:18 +08:00   ❤️ 1
    必要的地方一定要用,尤其是涉及业务处理的地方,
    例如 手机号已注册异常、订单已完成 /取消不允许改商品 /付款 等。

    先 try-catch,然后 catch 内判断判断环境,
    开发环境下重新 throw 出来,尽早暴露 bug 尽早解决,fail fast ;
    线上环境就写日志,以便追踪错误。

    在返回给 HTTP API 调用方(一般是写在 Controller 里面)前,
    把 Exception 转成 错误码 status 和 错误信息 message,
    毕竟人家可不想看到一堆后端的堆栈信息,而且没有 status 也不好处理。

    还有线上环境千万不能因为部分接口异常导致整个服务挂掉,
    虽然 SpringBoot 等框架会统一 catch 避免这种问题,
    并在 Response Header 返回 status 和 message,
    但还是自己 catch 到封装成业务状态码和错误信息更好,
    尤其是在 业务错误码 和 HTTP status 有重合的情况下会不好区分,
    HTTP status 更多地是用在连接状态上,
    自定义的 status 是用于自己的业务处理状态。
    TommyLemon
        9
    TommyLemon  
       2018-10-29 15:53:02 +08:00
    @TommyLemon 有些 SDK 抛的异常,有必要替换成你自己的,
    例如
    NoSuchMethodException("... did not find method getOrder, ..."),
    DuplicatedEntryException("... phone is a unique column and 12345 already exist ..."),
    可以换成自己封装的
    ServerException("服务器内部错误") ,
    ConflictException("手机号已注册")
    等,
    一方面可以更简单明确地告诉调用方出了什么问题,
    另一方面可以避免信息泄露( SQLSyntaxError 里面可能会有 SQL 片段,暴露出 表名、字段名等)
    flyingghost
        10
    flyingghost  
       2018-10-29 16:07:44 +08:00
    1,理论上你应该把“出了任何问题,通过日志可以分析出原因”作为目标去追求。毕竟后端有很多很微妙的 bug 或者漏洞很难重现。日志应该是最有力的分析工具。如果分析不出来,说明你没记录好。
    2,try/catch 我是这样使用的:
    2.1,可预期的,自己可处理的一般会拆成小的 try 当场给结论或者当场恢复掉。
    2.2,原则上不会给调用方暴露原始异常信息,一定是经过掩饰或者二次处理的信息。这个操作可以在业务层,也可以在中间件或者框架层。
    2.3,至于具体谁负责,看情况。有时候多方共同处理 /记录然后 rethrow 出去给上层做不同层面的处理也是常见的。
    zhangqilin
        11
    zhangqilin  
    OP
       2018-10-29 16:24:10 +08:00
    非常感谢
    huahuajun9527
        12
    huahuajun9527  
       2018-10-29 16:57:40 +08:00
    首先确定,定义好异常类型。一个函数的责任是有限的,出现不能处理的问题就往上抛,让上层调用者自己处理。

    PS:并不是将异常打印出来就算处理异常!!!
    itskingname
        13
    itskingname  
       2018-10-29 17:09:35 +08:00
    送你一个 Python 第三方库:tenacity
    zhangwugui
        14
    zhangwugui  
       2018-10-29 17:24:36 +08:00
    一般不都是使用全局的异常处理来解决么,exceptionhander。只有在必要的时候显示用 try/catch 吧
    glacer
        15
    glacer  
       2018-10-29 18:02:06 +08:00
    任何可能出现运行时错误的地方都需要 try/catch,比如 HTTP 请求,数据库操作等。
    如果错误能在 catch 块中被解决且不需要中断程序执行的,可在 catch 中修复继续执行。
    如果错误无法被解决,则在 catch 中 raise 到上层处理。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5892 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 01:48 · PVG 09:48 · LAX 17:48 · JFK 20:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.