我是Python新手,我偶然发现了一个异常处理问题。我正在编写一个简单的龙卷风+ momoko应用程序。总之,我有一个全局(?)对象是在主函数中创建的,该对象属于QueryExecutor类。它是一个使用momoko处理SQL查询执行的简单类。
class QueryExecutor:
def __init__(self, database):
self.db = database
@gen.engine
def _run(self, query):
self.db.execute(query, callback = (yield gen.Callback('q')))
try:
cursor = yield momoko.WaitOp('q')
except Exception as error:
print(str(error))
def save(self, tablename, data):
fields = "(" + ", ".join(map(str, list(data.keys()))) + ")"
values = "(" + "\'" + '\', \''.join(map(str, list(data.values()))) + "\'" + ")"
query = "INSERT INTO " + tablename + " " + fields + " VALUES " + values + ";"
self._run(query)我想要实现的是在请求处理程序中使用这个类的对象,并在某种程度上能够判断何时发生了异常:
class RegistrationHandler(tornado.web.RequestHandler):
def get(self):
self.render("templates/register.html")
def post(self):
#...handle post arguments, retrieve user data, check if correct etc., do stuff...
#...if everything ok:
queryExec.save("users", userdata)
#what to do if save threw an exception?
application.db = momoko.Pool(dsn=dbsetup.dsn, size=1)
if __name__ == "__main__":
queryExec = dbsetup.QueryExecutor(database=application.db)
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()当查询失败时,queryExec.save()会抛出一个异常,如果发生这种情况,我想在请求处理程序函数中知道。在try和not块中嵌入queryExec.save()不起作用。显然,我可能可以传递额外的参数(引用?)对于queryExec.save(),或者向QueryExecutor类本身添加某种状态参数,但是我想知道是否有更好的方法来解决这个问题?
编辑:修改后:
class TestEx(Exception): pass以及:
@gen.engine
def _run(self, query):
self.db.execute(query, callback = (yield gen.Callback('q')))
try:
cursor = yield momoko.WaitOp('q')
except Exception as error:
print(str(error))
raise TestEx("test exception")以及:
try:
queryExec.save("users", userdata)
except dbsetup.TestEx as ex:
print("exception caught in caller function")
self.redirect("templates/login.html")我进了控制台:
/usr/bin/python3.3 /home/tybur/PycharmProjects/tornadochat/main.py
duplicate key value violates unique constraint "unique_names"
DETAIL: Key (name)=(testuser) already exists.
ERROR:tornado.application:Exception in callback None
Traceback (most recent call last):
File "/home/tybur/PycharmProjects/tornadochat/dbsetup.py", line 46, in _run
cursor = yield momoko.WaitOp('q')
File "/usr/local/lib/python3.3/dist-packages/tornado/gen.py", line 520, in run
next = self.yield_point.get_result()
File "/usr/local/lib/python3.3/dist-packages/momoko/utils.py", line 59, in get_result
raise error
File "/usr/local/lib/python3.3/dist-packages/momoko/connection.py", line 244, in io_callback
state = self.connection.poll()
psycopg2.IntegrityError: duplicate key value violates unique constraint "unique_names"
DETAIL: Key (name)=(testuser) already exists.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.3/dist-packages/tornado/ioloop.py", line 688, in start
self._handlers[fd](fd, events)
File "/usr/local/lib/python3.3/dist-packages/tornado/stack_context.py", line 331, in wrapped
raise_exc_info(exc)
File "<string>", line 3, in raise_exc_info
File "/usr/local/lib/python3.3/dist-packages/tornado/stack_context.py", line 302, in wrapped
ret = fn(*args, **kwargs)
File "/usr/local/lib/python3.3/dist-packages/momoko/connection.py", line 248, in io_callback
self.callback(error)
File "/usr/local/lib/python3.3/dist-packages/tornado/stack_context.py", line 331, in wrapped
raise_exc_info(exc)
File "<string>", line 3, in raise_exc_info
File "/usr/local/lib/python3.3/dist-packages/tornado/stack_context.py", line 302, in wrapped
ret = fn(*args, **kwargs)
File "/usr/local/lib/python3.3/dist-packages/tornado/gen.py", line 574, in inner
self.set_result(key, result)
File "/usr/local/lib/python3.3/dist-packages/tornado/gen.py", line 500, in set_result
self.run()
File "/usr/local/lib/python3.3/dist-packages/tornado/gen.py", line 529, in run
yielded = self.gen.throw(*exc_info)
File "/home/tybur/PycharmProjects/tornadochat/dbsetup.py", line 49, in _run
raise TestEx("test exception")
dbsetup.TestEx: test exception发布于 2014-02-05 00:53:20
save()不会引发异常;它会启动对_run的调用,但不会等待它,因此除了记录异常之外,没有什么地方可以让异常发生。要解决这个问题,您应该遵循三条规则:
@gen.engine,否则应该使用@gen.coroutine,这使事情更像正常的函数。Future”,则应该保存它的返回值( Future,它是其实际结果的占位符),并在以后生成它(您可能希望这样做,并行启动几个coroutine,并同时等待它们)。因此,在本例中,创建save()、_run()和post()协同,并在调用_run()和save()时使用_run()关键字。
https://stackoverflow.com/questions/21556658
复制相似问题