Flask 构建 Web API Wheel(七)—— 异常处理

Updated on in Python with 827 views

Flask 在请求出现异常时一般会抛出 HTTPException,他会把异常信息以页面的形式展示,这对一个API项目来说是多余的,我们可以通过继承 HTTPException 返回自己想要的结构。

比如一般请求中需要用 data、msg、msg_code 这些字段。并且规划好不同的 msg_code 代表了什么信息。

{
	data: null,
	msg: "Token不合法",
	msg_code: 10010
}

异常处理基类

通过覆写 HTTPException 的 get_body()、get_headers(),使其返回 JSON 结构。

在 HTTP 状态码的返回上,不同的项目会有不同的选择,如果追求 RESTful 风格的返回,也就是比如在资源找不到时必须返回 404,创建资源成功返回 201 等,这样严格按照规范来做的话需要在配置中把 RESTFUL_HTTP_CODE 设置为 True。

默认 RESTFUL_HTTP_CODE 是关闭的,因为在很多时候这个规范也并非强制的,状态码返回200 更便于前端操作。

class APIException(HTTPException):
    code = 500
    msg_code = 9999
    data = None
    msg = '服务器未知错误'
    headers = {'Content-Type': 'application/json'}

    def __init__(self, data=None, code=None, msg_code=None, msg=None, headers=None):
        if data:
            self.data = data
        if msg_code:
            self.msg_code = msg_code
        if msg:
            self.msg = msg
        if headers:
            self.headers = headers

        # 状态码返回风格
        if current_app.config['RESTFUL_HTTP_CODE']:
            if code:
                self.code = code
        else:
            self.code = 200

        super(APIException, self).__init__()

    def get_body(self, environ=None):
        body = dict(
            msg_code=self.msg_code,
            msg=self.msg,
            data=self.data
        )
        return json.dumps(body)

    def get_headers(self, environ=None):
        return [(k, v) for k, v in self.headers.items()]


# --- 成功 0~999 ---
class Success(APIException):
    code = 200
    msg_code = 0
    msg = '成功'


class Created(APIException):
    code = 201
    msg_code = 1
    msg = '创建成功'


class Updated(APIException):
    code = 201
    msg_code = 2
    msg = '更新成功'


class Deleted(APIException):
    code = 202
    msg_code = 3
    msg = '删除成功'

全局异常处理

Flask 可以捕获全局异常,我们将异常都以 APIException 的形式抛出,在开发环境下未知的异常任然以堆栈形式抛出,以方便调试。

def register_exception(app):
    @app.errorhandler(Exception)
    def handle_error(e):
        if isinstance(e, APIException):
            return e
        elif isinstance(e, HTTPException):
            return APIException(code=e.code, msg=e.name)
        else:
            if not app.config['DEBUG']:
                return ServerError()
            raise e

标题:Flask 构建 Web API Wheel(七)—— 异常处理
作者:Jeffrey

Responses
取消