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
tywtyw2002
V2EX  ›  Python

关于 tornado 的两个问题

  •  
  •   tywtyw2002 · 2014-03-21 16:21:20 +08:00 · 4303 次点击
    这是一个创建于 3692 天前的主题,其中的信息可能已经有所发展或是发生改变。
    一、tornado 如何才能stop整个请求链然后去抛出错误呢?
    比如说,进入了ManageHandler的get,
    get在查询数据库,数据库错误了,raise了一个database的error,
    接下来error handler把这个错误给接管了,抛出一个错误页面,然后结束这个请求链。
    用finish()去结束的话报错。。。。。


    二、也是关于请求链终止的问题。
    比如说,进入了ManageHandler的get,
    但是ManageHandler要在 init的时候判断下用户的权限,如果用户的权限不够,直接抛出404页面。
    class ManageHandler(BaseHandler):

    def __init__(self, *argc, **argkw):
    super(ManageHandler, self).__init__(*argc, **argkw)
    self.private_auth()


    def private_auth(self):
    self.user = self.get_secure_cookie("user")
    self.private = self.UserModel.get_user_level_by_name(self.user)

    #not login
    if self.private == -1:
    return

    if self.private != 4:
    self.render("404.html")
    self.finish()
    然后这样用finish也报错
    [E 140321 02:06:04 iostream:357] Uncaught exception, closing connection.
    Traceback (most recent call last):
    File "/Library/Python/2.7/site-packages/tornado/iostream.py", line 354, in wrapper
    callback(*args)
    File "/Library/Python/2.7/site-packages/tornado/stack_context.py", line 331, in wrapped
    raise_exc_info(exc)
    File "/Library/Python/2.7/site-packages/tornado/stack_context.py", line 302, in wrapped
    ret = fn(*args, **kwargs)
    File "/Library/Python/2.7/site-packages/tornado/httpserver.py", line 328, in _on_headers
    self.request_callback(self._request)
    File "/Library/Python/2.7/site-packages/tornado/web.py", line 1651, in __call__
    handler = spec.handler_class(self, request, **spec.kwargs)
    File "/Users/tyw/Workspaces/CMPUT391/trunk/app/handlers/ManageHandler.py", line 23, in __init__
    self.private_auth()
    File "/Users/tyw/Workspaces/CMPUT391/trunk/app/handlers/ManageHandler.py", line 36, in private_auth
    self.finish()
    File "/Library/Python/2.7/site-packages/tornado/web.py", line 837, in finish
    self.flush(include_footers=True)
    File "/Library/Python/2.7/site-packages/tornado/web.py", line 784, in flush
    for transform in self._transforms:
    TypeError: 'NoneType' object is not iterable
    [E 140321 02:06:04 ioloop:491] Exception in callback <functools.partial object at 0x10c63e1b0>
    Traceback (most recent call last):
    File "/Library/Python/2.7/site-packages/tornado/ioloop.py", line 477, in _run_callback
    callback()
    File "/Library/Python/2.7/site-packages/tornado/stack_context.py", line 331, in wrapped
    raise_exc_info(exc)
    File "/Library/Python/2.7/site-packages/tornado/stack_context.py", line 302, in wrapped
    ret = fn(*args, **kwargs)
    File "/Library/Python/2.7/site-packages/tornado/iostream.py", line 354, in wrapper
    callback(*args)
    File "/Library/Python/2.7/site-packages/tornado/stack_context.py", line 331, in wrapped
    raise_exc_info(exc)
    File "/Library/Python/2.7/site-packages/tornado/stack_context.py", line 302, in wrapped
    ret = fn(*args, **kwargs)
    File "/Library/Python/2.7/site-packages/tornado/httpserver.py", line 328, in _on_headers
    self.request_callback(self._request)
    File "/Library/Python/2.7/site-packages/tornado/web.py", line 1651, in __call__
    handler = spec.handler_class(self, request, **spec.kwargs)
    File "/Users/tyw/Workspaces/CMPUT391/trunk/app/handlers/ManageHandler.py", line 23, in __init__
    self.private_auth()
    File "/Users/tyw/Workspaces/CMPUT391/trunk/app/handlers/ManageHandler.py", line 36, in private_auth
    self.finish()
    File "/Library/Python/2.7/site-packages/tornado/web.py", line 837, in finish
    self.flush(include_footers=True)
    File "/Library/Python/2.7/site-packages/tornado/web.py", line 784, in flush
    for transform in self._transforms:
    TypeError: 'NoneType' object is not iterable
    9 条回复    1970-01-01 08:00:00 +08:00
    binux
        1
    binux  
       2014-03-21 16:26:52 +08:00
    我觉得是你用法有误

    一、抛异常本来就不会继续执行啊
    二、在get里面调self.private_auth(),如果不成功 return 掉就好了
    tywtyw2002
        2
    tywtyw2002  
    OP
       2014-03-21 16:30:45 +08:00
    @binux 我在init里面掉是因为 有6个 get/post都用这个 private_auth(), 那些class 都继承在这个class的下面,我想这样可能方便一些。
    binux
        3
    binux  
       2014-03-21 16:50:15 +08:00
    tywtyw2002
        4
    tywtyw2002  
    OP
       2014-03-21 16:54:57 +08:00
    @binux User authentication 不是只判断用户是否登录了吗,没登陆的话跳到login页面。

    我看了tornado自带的,没有发现他能跳到一个错误页面呀。
    binux
        5
    binux  
       2014-03-21 17:09:57 +08:00
    @tywtyw2002
    1、 login url 是可以设置的(不建议)
    2、 在 get_current_user 里面 raise HTTPError(404)
    3、 再写一个修饰器
    ushuz
        6
    ushuz  
       2014-03-21 17:14:27 +08:00 via iPhone
    async才需要自己调finish
    raise tornado.web.HTTPError(404)来抛出异常,看文档里面有怎么自定义错误页面
    walleL
        7
    walleL  
       2014-03-21 19:04:35 +08:00   ❤️ 1
    zeayes
        8
    zeayes  
       2014-03-24 22:32:21 +08:00
    @ushuz 是这样的,async需要自己finish,否则tornado自动finish。

    问题1:楼主可以用异步请求,catch住异常,再处理。

    问题2:可以用装饰器处理。
    tywtyw2002
        9
    tywtyw2002  
    OP
       2014-03-25 02:08:13 +08:00 via iPhone
    @walleL thanks
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4682 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 01:08 · PVG 09:08 · LAX 18:08 · JFK 21:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.