flask入门到起飞(十三)结合flask-wtf框架异常统一json格式处理

96
aimaile
2018.11.01 00:28 字数 85

已知异常处理

wtf框架在处理数据校验的时候并不会把异常给抛出来,而是存放在表单的error里面,这里为了遵循restflu风格,统一把异常抛出来,统一json格式。

from flask import request, json
from werkzeug.exceptions import HTTPException

class APIException(HTTPException):
    code = 500
    msg = 'server error'
    error_code = 999

    def __init__(self, msg=None, code=None, error_code=None,
                 headers=None):
        if code:
            self.code = code
        if error_code:
            self.error_code = error_code
        if msg:
            self.msg = msg
        super(APIException, self).__init__(msg, None)
    
    #重写了get-body方法
    def get_body(self, environ=None):
        #错误返回的格式
        body = dict(
            msg=self.msg,
            error_code=self.error_code,
            request=request.method + ' ' + self.get_url_no_param()
        )
        text = json.dumps(body)
        return text
    
    #重写了get_headers方法
    def get_headers(self, environ=None):
        """Get a list of headers."""
        return [('Content-Type', 'application/json')]

    @staticmethod
    def get_url_no_param():
        full_path = str(request.full_path)
        main_path = full_path.split('?')
        return main_path[0]
from flask import request
from wtforms import Form
from app.libs.error import ParameterException 

#重新Form,编写form基类,异常抛出(注意wtf发生异常不会抛出)
class BaseForm(Form):
    def __init__(self):
        data = request.get_json(silent=True)
        args = request.args.to_dict()
        super(BaseForm, self).__init__(data=data, **args)

    def validate_for_api(self):
        valid = super(BaseForm, self).validate()
        if not valid:
            # form errors
            raise ParameterException(msg=self.errors)
        return self


class LoginForm(BaseForm):
                                             #不允许为空'为异常抛出是存储在form,error中错误信息
    account = StringField(validators=[DataRequired(message='不允许为空'), length(
        min=5, max=32
    )])
    secret = StringField()
    type = IntegerField(validators=[DataRequired()])
    
    #自定义验证字段
    def validate_type(self, value):
        try:
            #枚举类型转化
            client_type =  TypeEnum(value.data)
        except ValueError as e:
            raise e
         #满足条件,重新赋值
        self.type.data = client_type 

#怎样校验json数据是否合法
loginForm = LoginForm(data = request.json)
loginForm.validate_for_api进行合法性判断,然后处理相关的业务逻辑

未知异常处理 AOP,利用flask提供的钩子函数

@app.errorhandler(Exception)
def framework_error(e):
    if isinstance(e, APIException):
        return e
    if isinstance(e, HTTPException):
        code = e.code
        msg = e.description
        error_code = 1007
        return APIException(msg, code, error_code)
    else:
        # 调试模式关闭不会打开堆栈信息,开发阶段为了快速定位问题,都打开了调试模式
        # log记录,后续对错误日子分析处理的
        if not app.config['DEBUG']:
            return APIException()
        else:
            raise e
flask
Web note ad 1