如何避免 Tornado RequestHandler 中混乱的错误处理
How to avoid messy error handling in Tornado RequestHandler
假设我有一个像这样的简单 RequestHandler
。
class RequestHandler(web.RequestHandler):
def get(self, id, status):
obj = self.retrieve_object(id)
obj.update({"status": status})
self.write(json.dumps(obj))
问题是,每当处理程序出现错误时,它都会 return 错误 500(内部服务器错误)。显然我想 return 一个错误 400 而不是当用户输入了一些无效的东西时。
所以我必须添加一堆错误检查,像这样:
class RequestHandler(web.RequestHandler):
def get(self, id, status):
try:
id = int(id)
except ValueError:
raise web.HTTPError(400, "Invalid id")
if status not in ("open", "closed"):
raise web.HTTPError(400, "Invalid status")
try:
obj = self.retrieve_object(id)
except ObjDoesntExistError:
raise web.HTTPError(400, "Object doesn't exist")
obj.update({"status": status})
self.write(json.dumps(obj))
问题是这会使函数变得非常臃肿。有没有更清洁的方法来做到这一点?还是无法避免?
如果你想在多个处理程序中执行相同的检查,你可以只创建一个基 class:
class BaseHandler(web.RequestHandler):
def prepare(self):
id = self.path_args[0]
status = self.path_args[1]
try:
id = int(id)
except ValueError:
raise web.HTTPError(400, "Invalid id")
# ... and so on ...
现在,只需继承这个基础class,代码将被重用。
假设我有一个像这样的简单 RequestHandler
。
class RequestHandler(web.RequestHandler):
def get(self, id, status):
obj = self.retrieve_object(id)
obj.update({"status": status})
self.write(json.dumps(obj))
问题是,每当处理程序出现错误时,它都会 return 错误 500(内部服务器错误)。显然我想 return 一个错误 400 而不是当用户输入了一些无效的东西时。
所以我必须添加一堆错误检查,像这样:
class RequestHandler(web.RequestHandler):
def get(self, id, status):
try:
id = int(id)
except ValueError:
raise web.HTTPError(400, "Invalid id")
if status not in ("open", "closed"):
raise web.HTTPError(400, "Invalid status")
try:
obj = self.retrieve_object(id)
except ObjDoesntExistError:
raise web.HTTPError(400, "Object doesn't exist")
obj.update({"status": status})
self.write(json.dumps(obj))
问题是这会使函数变得非常臃肿。有没有更清洁的方法来做到这一点?还是无法避免?
如果你想在多个处理程序中执行相同的检查,你可以只创建一个基 class:
class BaseHandler(web.RequestHandler):
def prepare(self):
id = self.path_args[0]
status = self.path_args[1]
try:
id = int(id)
except ValueError:
raise web.HTTPError(400, "Invalid id")
# ... and so on ...
现在,只需继承这个基础class,代码将被重用。