如何避免 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,代码将被重用。