2017-05-12 1 views
0

Nous avons un projet Python 2 dans lequel nous utilisons activement des coroutines. Nous ne pouvons pas trouver de directives sur la gestion des exceptions à l'intérieur des coroutines. Par exemple, here développeur principal de Tornado mentionné coroutines should never raise an exception, mais il n'est pas clair pourquoi. On dirait que cette approche fonctionne et fortement utilisé dans Tornado.web lui-même:Soulevez l'exception ou renvoyez l'objet gen.Return dans la coroutine Tornado

https://github.com/tornadoweb/tornado/blob/master/demos/blog/blog.py#L180

class AuthCreateHandler(BaseHandler): 
    def get(self): 
     self.render("create_author.html") 

    @gen.coroutine 
    def post(self): 
     if self.any_author_exists(): 
      raise tornado.web.HTTPError(400, "author already created") 
     hashed_password = yield executor.submit(
      bcrypt.hashpw, tornado.escape.utf8(self.get_argument("password")), 
      bcrypt.gensalt()) 

tornado.web.HTTPError étend juste la base Exception classe. De plus, la discussion ici https://github.com/tornadoweb/tornado/issues/759#issuecomment-91817197 suggère que l'augmentation de l'exception à l'intérieur de la coroutine est appropriée.

également here, contributeur de Tornado actif suggère que l'augmentation des exceptions est très bien:

class PostHandler(tornado.web.RequestHandler): 
    @gen.coroutine 
    def get(self, slug): 
     post = yield db.posts.find_one({'slug': slug}) 
     if not post: 
      raise tornado.web.HTTPError(404) 

     self.render('post.html', post=post) 

Y at-il des inconvénients à soulever des exceptions à l'intérieur Tornado coroutines ou devrions-nous raise gen.Return(exception_object)?

Répondre

4

En Python 2, utilisez uniquement raise gen.Return(value) pour renvoyer une valeur normale, pas pour déclencher une exception. C'est exactement l'équivalent de return value dans une coroutine en Python 3.

Pour générer une exception à partir d'une coroutine, un raise Exception() normal est correct. La chose merveilleuse au sujet des coroutines est leur sémantique de manipulation d'exception est à peu près la même chose que les fonctions régulières.

3

La levée d'exceptions à l'intérieur des coroutines est parfaitement normale. Quand j'ai dit "coroutines ne devrait jamais soulever une exception" je faisais référence à appeler un coroutine sans yield ou await: L'exception est capturée et maintenue jusqu'à ce que la valeur de retour du coroutine soit yielded ou awaited.