最近在看后台日志,一堆 try/except 后打印出的错误信息 但有这么一堆错误信息还是排查不出问题 我自己维护的项目中 try/except 很少,因为我觉得运用大量的 try 只是掩盖了问题,而不是去解决问题
而实际上我在维护别人项目的时候,比如一个接口的代码为:
这样在服务器日志里看到有打印出来的错误信息,很不爽,想去解决 但又找不到问题出在哪儿,因为报的也不多 可能是强迫症吧
因为这是我第一个公司,所以想问一下 V2EX 的同志们
究竟是大片的 try/except 好?还是几乎不写 try/except 好
或者说
try/except 究竟应该在哪些场合应用?
1
cy97cool 2018-10-29 14:31:08 +08:00
赶紧用 sentry
只有异常是期待中的 才需要用 except 否则就丢给上一层调用者处理 不该处理的异常就别处理 并非 try-except 写的多就程序更健壮更靠谱 出错了就返回 fail 即使不用 sentry 至少也应该同时记录一下 traceback.print_exc() |
2
janus77 2018-10-29 14:32:52 +08:00
不是越多越好,但是该用的地方肯定要用的啊
|
3
p2pCoder 2018-10-29 14:35:22 +08:00
你还不会打日志,这是最大的问题
很多地方 try except 是必要的,这是程序健壮性必须的 后端接口,不要直接把 exception 直接抛给 接口调用方,无论调用方是 web 前端,还是其他服务 调用方并不关心你究竟又啥异常 楼主还是多向公司有经验的问问,日志打不好,排查线上问题是很老火的 |
4
owenliang 2018-10-29 14:54:42 +08:00
我觉得框架捕获就可以,业务代码别处理那么多异常。
框架捕获了该打日志打日志,该采集采集,能追查能报警就很好。 |
5
TheWalkingDead 2018-10-29 15:01:48 +08:00
这是打日志的问题,即使用了 try except,也可以完整的打印出异常栈
|
6
welkinzh 2018-10-29 15:03:11 +08:00
是日志没反映出问题,不能怪 try/except
|
7
xuanbg 2018-10-29 15:26:47 +08:00
异常处理里面没有业务逻辑的话,还是交给框架去捕获好了。
|
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 是用于自己的业务处理状态。 |
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 片段,暴露出 表名、字段名等) |
10
flyingghost 2018-10-29 16:07:44 +08:00
1,理论上你应该把“出了任何问题,通过日志可以分析出原因”作为目标去追求。毕竟后端有很多很微妙的 bug 或者漏洞很难重现。日志应该是最有力的分析工具。如果分析不出来,说明你没记录好。
2,try/catch 我是这样使用的: 2.1,可预期的,自己可处理的一般会拆成小的 try 当场给结论或者当场恢复掉。 2.2,原则上不会给调用方暴露原始异常信息,一定是经过掩饰或者二次处理的信息。这个操作可以在业务层,也可以在中间件或者框架层。 2.3,至于具体谁负责,看情况。有时候多方共同处理 /记录然后 rethrow 出去给上层做不同层面的处理也是常见的。 |
11
zhangqilin OP 非常感谢
|
12
huahuajun9527 2018-10-29 16:57:40 +08:00
首先确定,定义好异常类型。一个函数的责任是有限的,出现不能处理的问题就往上抛,让上层调用者自己处理。
PS:并不是将异常打印出来就算处理异常!!! |
13
itskingname 2018-10-29 17:09:35 +08:00
送你一个 Python 第三方库:tenacity
|
14
zhangwugui 2018-10-29 17:24:36 +08:00
一般不都是使用全局的异常处理来解决么,exceptionhander。只有在必要的时候显示用 try/catch 吧
|
15
glacer 2018-10-29 18:02:06 +08:00
任何可能出现运行时错误的地方都需要 try/catch,比如 HTTP 请求,数据库操作等。
如果错误能在 catch 块中被解决且不需要中断程序执行的,可在 catch 中修复继续执行。 如果错误无法被解决,则在 catch 中 raise 到上层处理。 |