V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
billgreen1
V2EX  ›  Python

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

  •  
  •   billgreen1 · 2016-01-14 07:39:16 +08:00 · 7039 次点击
    这是一个创建于 3026 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我现在在写得一个小程序,基本逻辑是,输入是一个 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 比较好? 你们通常是怎么做的?

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

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

    有一些特殊情况,例如 python encode 时,如果单个字符解码错误默认直接抛出异常,不过 python 标准库提供了一个参数,允许忽略单个错误。
    Reed
        12
    Reed  
       2016-01-14 20:08:44 +08:00
    我是直接 logger.exception(e),所有的异常信息都被记录了。
    billgreen1
        13
    billgreen1  
    OP
       2016-01-14 20:18:10 +08:00
    @Reed 你是在 func1 这样的函数里面 logger 还是在 main 函数里面来 try except 然后 log ?
    billgreen1
        14
    billgreen1  
    OP
       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
        15
    yuelang85  
       2016-01-14 20:27:53 +08:00
    @billgreen1 是的,就是这个思路
    glasslion
        16
    glasslion  
       2016-01-17 00:33:23 +08:00
    抛异常, sentry 处理
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3014 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 08:35 · PVG 16:35 · LAX 01:35 · JFK 04:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.