当前位置: 首页 > 知识库问答 >
问题:

如何捕获gen.任务中的异常?

张德佑
2023-03-14

我使用的是python 2.7和tornado 4.5

以下代码不起作用:除块不被触发。我不明白为什么?

@gen.coroutine
def co_do_thing():
  yield gen.Task(do_thing)

def do_thing(callback):
  try:
    a, b = ...
    result = maybe_throw(a, b, callback)
  except Exception as e:
    # this block is not called
    if a:
      raise ApiError("called with A")
    elif b:
      raise ApiError("called with B")
    else:
      raise e

def maybe_throw(arg1, arg2, callback):
  if random.random() < 0.5:
    raise AssertionError("yikes")
  callback("done")

相反,我可以捕获gen调用周围的co_do_thing中的异常。任务;但是我没有我如何调用maybe_throw的上下文。在我的例子中,更有意义的是maybe_throw引发一个较低级别的异常,并且调用者根据输入将其转换为人类可读的错误。

我是否只需要重构它来调用较低级别的gen.Task?那会很烦人:/

共有1个答案

宓跃
2023-03-14

当我测试它似乎工作,一个例外被提出。下面是简单的测试套件:

import q  # q.py is the file with question's code

import unittest
from mock import patch, Mock
from tornado.testing import gen_test, AsyncTestCase


class MyTest(AsyncTestCase):

    def setUp(self):
        self.mock_random = patch('q.random').start()
        AsyncTestCase.setUp(self)

    def tearDown(self):
        AsyncTestCase.tearDown(self)
        patch.stopall()

    @gen_test
    def test_no_error(self):
        self.mock_random.return_value = 0.7
        res = yield q.co_do_thing()
        self.assertEqual(res, 'done')

    @gen_test
    def test_exception(self):
        self.mock_random.return_value = 0.1
        with self.assertRaises(Exception) as ctx:
            yield q.co_do_thing()
        self.assertEqual(ctx.exception.message, 'called with A')


if __name__ == '__main__':
    unittest.main()

通过的测试:

..
----------------------------------------------------------------------
Ran 2 tests in 0.002s

OK

这里是q.py,我添加了返回语句来测试它。

from random import random
from tornado import gen

@gen.coroutine
def co_do_thing():
    res = yield gen.Task(do_thing)
    # added: to enable to test it meaningfully
    raise gen.Return(res)

def do_thing(callback):
    try:
        a, b = 22, 33
        result = maybe_throw(a, b, callback)
    except Exception as e:
        if a:
            raise Exception("called with A")
        elif b:
            raise Exception("called with B")
        else:
            raise e

def maybe_throw(arg1, arg2, callback):
    if random() < 0.5:
        raise AssertionError("yikes")
    callback("done")

 类似资料:
  • 本文向大家介绍如何在Clojurescript中捕获任何JavaScript异常?,包括了如何在Clojurescript中捕获任何JavaScript异常?的使用技巧和注意事项,需要的朋友参考一下 要在Clojurescript中捕获JavaScript异常,请尝试以下代码片段-

  • 我有一个骡子流,可以抛出异常(无法连接到连接器,组件抛出异常等)。当这种情况发生时,骡子流在异常发生的地方停止。我需要捕获流抛出的任何异常并发送电子邮件通知,指示发生了异常。(尤其是对于像从JMS读取一样异步运行的流)。我应该使用流中的什么元素来捕获任何异常并发送电子邮件? 我试过了: 但这根本就没有开始。我还尝试过: 但这似乎只在流抛出异常时才有效(正常的流功能被改变)。 @David Doss

  • 我正在用。NET核心编写一个ASP.NET MVC站点。我试图封装一些常见的异常处理。在基类中,我有这个方法。 从继承自该基类的控制器中,我使用如下方法: 假设_someservice.getAsync()方法如下: 这工作得很好,将捕获基类方法中的异常并返回NotFound结果。 但是,我希望避免从SomeService.GetAsync方法调用。result。我读到的任何地方都说不要那样做,因

  • 问题内容: 我如何编写一个块来捕获所有异常? 问题答案: 你可以,但你可能不应该: 但是,这也会捕获类似的异常,而你通常不希望那样,对吗?除非你立即重新引发异常,否则请参阅docs中的以下示例:

  • 我正在尝试将一个任务提交给Java的ExecutorService。它要么需要一个Callable,它允许抛出异常,要么需要一个Runnable。我的用例是愚蠢的:我想安排一个抛出异常的任务,但它是一个无效的方法。因此,我不能使用Callable或Runnable,因为方法定义与我的用例不匹配。我还想让我的异常从提交后收到的Future传播。有什么想法吗?

  • 我用的是spring-boot和JPA。我试图捕捉未检查的异常,如(违反约束)引发的事务。即使我添加了catch块,它也会在超出事务边界时抛出。 我谷歌了一下,发现可以通过事务回调来实现。我尝试了下面的代码:仍然是给出错误 请帮帮我!!