关于异常,你们是抛出,还是直接 log 打印?

2016-01-14 07:39:16 +08:00
 billgreen1

我现在在写得一个小程序,基本逻辑是,输入是一个 generator ,在程序里面对每个元素进行处理,输出一个新的 generator 。

def main():
          data_gen  = xrange(10) # just an example
          data1 = func1(data_gen)
          data2 = func2(data1)
      ...
def func1(data_gen):
          for element in data_gen:
                try:
                     ret = process(element)
                except Exception, e:
                     logger.error(e.message)   # 我的处理
                     raise  # 网上看到其他人的处理
                else:
                     yield ret

func2,func3 逻辑大致相同。
通常出现的异常主要有:数据长度不够,本应该有数据却有 None 值,等。不是很频繁。
我的目标是:对于『正常的 element 』返回正确的结果。 出现异常, 记录下异常的原因。(我通常写, func1 expect XX rows, however database returns YY rows.)

我的问题是,什么情况下用 raise 比较好? 你们通常是怎么做的?

7243 次点击
所在节点    Python
16 条回复
des
2016-01-14 07:43:21 +08:00
如果是致命异常就抛出,
janxin
2016-01-14 07:57:03 +08:00
看类型,如果是顶层应用,原则是尽量处理并日志记录。下层基本是抛异常。
ttycode
2016-01-14 07:59:27 +08:00
这就看你怎么区分了,一般来说根据严重程度分为错误和异常,错误是业务逻辑的一个部分,就是不会影响其他逻辑处理,这个记录日志就好了。而异常就是这个问题影响到其他的处理了,比如说数据库坏了这种事情就是异常,没它大家都完成不了逻辑处理。说不是绝对,是因为足够多的错误也应该视为异常,有可能是外部人为攻击行为。这种就要将错误升级为异常行为。
monnand
2016-01-14 08:50:52 +08:00
不用异常,全部错误显示处理,尽量把各种事件都记录下来。异常乱抛最后调 bug 倒霉的还是自己
sujin190
2016-01-14 09:30:46 +08:00
日志写太多反而没用了,太多的日志你能不能找到错误点不说,都不知道哪写出来的,还是分层不同处理比较好,应用层核心点统一处理标准日志,尽可能收集信息,业务错误另外再写,底层尽可能抛出异常不写日志
billgreen1
2016-01-14 09:34:11 +08:00
@sujin190 能详细说说嘛,举个例子?感觉比较认同你的想法,但是有点模糊,要是有个例子来加深理解就好了。
bobuick
2016-01-14 10:02:22 +08:00
没办法继续了,或者继续下去意义不大且消耗太多, 果断抛异常出去, 特别是用 golang , 否则满天满地的 if err != nil {blabla}
hqs123
2016-01-14 10:04:18 +08:00
log 打印慢慢分析.
strahe
2016-01-14 10:07:17 +08:00
下层都是抛出,上层根据抛出的异常处理,最后仍出去的是友好的
yuelang85
2016-01-14 10:51:39 +08:00
抛出异常-》最外层捕获异常-》生成 log 内容-》打印 log -》 log 内容发送邮件

大概这么个流程
gamexg
2016-01-14 11:13:02 +08:00
一般都是底层抛异常,顶层处理并记录。
比较简单的方式是把自己写的底层可复用的代码按库的方式写。
比如库一般通过错误、异常向调用方报告错误,而不是输出日志并隐藏错误。

有一些特殊情况,例如 python encode 时,如果单个字符解码错误默认直接抛出异常,不过 python 标准库提供了一个参数,允许忽略单个错误。
Reed
2016-01-14 20:08:44 +08:00
我是直接 logger.exception(e),所有的异常信息都被记录了。
billgreen1
2016-01-14 20:18:10 +08:00
@Reed 你是在 func1 这样的函数里面 logger 还是在 main 函数里面来 try except 然后 log ?
billgreen1
2016-01-14 20:20:57 +08:00
@yuelang85 @gamexg

是 func1 这样的函数里面仅仅 raise ,然后在 main 函数里面
try:
data_gen = xrange(10) # just an example
data1 = func1(data_gen)
data2 = func2(data1)
...
except Exception, e:
logger.exception(e)

是这样吗?
yuelang85
2016-01-14 20:27:53 +08:00
@billgreen1 是的,就是这个思路
glasslion
2016-01-17 00:33:23 +08:00
抛异常, sentry 处理

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

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

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

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

© 2021 V2EX