我们要实现下图所示,报错后返回json格式的信息,相当于把默认的html格式的异常变成json格式的。
但是我们继承了HTTPException就会出现下图的结果:
首先异常分为两种:
- 完全可以预知的异常 已知异常 可以手动抛出我们定义好的APIException
- 我们完全没有意识到的异常 未知异常
已知异常的编写:
完整代码如下:
from flask import request, json
from werkzeug.exceptions import HTTPException
__author__ = 'jenrey'
class APIException(HTTPException):
code = 500
msg = 'sorry, we made a mistake (* ̄︶ ̄)!'
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)
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
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 werkzeug.exceptions import HTTPException
from app.libs.error import APIException
__author__ = 'jenrey'
class Success(APIException):
code = 201
msg = 'ok'
error_code = 0
class DeleteSuccess(Success):
code = 202
error_code = 1
class ServerError(APIException):
code = 500
msg = 'sorry, we made a mistake (* ̄︶ ̄)!'
error_code = 999
class ClientTypeError(APIException):
# 400 401 403 404
# 500
# 200 201 204
# 301 302
code = 400
msg = 'client is invalid'
error_code = 1006
class ParameterException(APIException):
code = 400
msg = 'invalid parameter'
error_code = 1000
class NotFound(APIException):
code = 404
msg = 'the resource are not found O__O...'
error_code = 1001
class AuthFailed(APIException):
code = 401
error_code = 1005
msg = 'authorization failed'
class Forbidden(APIException):
code = 403
error_code = 1004
msg = 'forbidden, not in scope'
class DuplicateGift(APIException):
code = 400
error_code = 2001
msg = 'the current book has already in gift'
最后的实现效果:
未知异常(全局处理异常):
用到AOP思想,不管异常发生在哪里,我只需要在全局的地方获取到所有的异常,然后统一来处理未知异常就可以解决我们的问题了。
就好像:我们的代码是迷宫一样,未知异常有可能发生在迷宫的任何一个地方,但是不管你发生在什么地方,我都在迷宫的出口处堵住你,这样就ok了。
flask提供了一个叫@app.errorhandler()装饰器
使用Exception是因为要捕获所有的异常,这里注意要使用flask1.0版本,以为在老的版本是不能捕获所有异常的。
比如在0.12这个版本里是不能传入Exception是无效的,只能传入特定的异常,比如传NotFound或者是404,但是他们是等价的,因为NotFound里面的code码就是404
因为我们捕捉的是基类的Exception,所以他有可能是APIException,或者HTTPException或者就是python最原始的Exception,所以我们要对这三种情况分别做处理。
当然我们也可以增加一个调试模式,如果是调试模式,就返回原本的详细信息。
这里的ServerError()就是默认的不传入参数的APIException,只不过我们后来给提取出来了。不用管。