[toc]html
1. abort()
abort()函数也叫视图终止函数,用于提早退出一个请求,并用指定的错误码返回。既然是视图终止函数,就是说abort()函数是写在视图中的。那么这个函数就不能处理因为url不合法引发的异常,由于一旦url不合法,是没法进入到视图函数中的。前端
flask-restful中的 abort() 的代码是封装的 flask 的 abort() 代码。python
flask abort() 源码:json
def abort(status, *args, **kwargs): return _aborter(status, *args, **kwargs)
flask-restful 的 abort() 源码:flask
def abort(http_status_code, **kwargs): try: original_flask_abort(http_status_code) except HTTPException as e: if len(kwargs): e.data = kwargs raise
这里的 original_flask_abort() 即 flask 的 abort()。其实咱们也能够本身来封装abort()这个函数,来实现咱们须要的功能。服务器
1.1 使用方式一:传递一个错误码
from flask import abort @app.route("/") def index(): # abort函数能够提早终止视图函数 abort(404) # 下面这条消息没法打印出来,由于上面abort函数已经终止了这个视图函数的运行。 print("我还在运行ing") return "Index Page"
参数http_status_code:传递状态码(错误码),必须是标准的http状态码。restful
直接返回给前端页面一个对应错误码的错误信息。app
查看错误码:函数
from werkzeug.exceptions import default_exceptions import pprint pprint.pprint(default_exceptions)
结果:ui
若是是如下列表以外的,会报服务器内部错误:{"message": "Internal Server Error"} 能够看到2xx与3xx并不在此之列。
{400: <class 'werkzeug.exceptions.BadRequest'>, 401: <class 'werkzeug.exceptions.Unauthorized'>, 403: <class 'werkzeug.exceptions.Forbidden'>, 404: <class 'werkzeug.exceptions.NotFound'>, 405: <class 'werkzeug.exceptions.MethodNotAllowed'>, 406: <class 'werkzeug.exceptions.NotAcceptable'>, 408: <class 'werkzeug.exceptions.RequestTimeout'>, 409: <class 'werkzeug.exceptions.Conflict'>, 410: <class 'werkzeug.exceptions.Gone'>, 411: <class 'werkzeug.exceptions.LengthRequired'>, 412: <class 'werkzeug.exceptions.PreconditionFailed'>, 413: <class 'werkzeug.exceptions.RequestEntityTooLarge'>, 414: <class 'werkzeug.exceptions.RequestURITooLarge'>, 415: <class 'werkzeug.exceptions.UnsupportedMediaType'>, 416: <class 'werkzeug.exceptions.RequestedRangeNotSatisfiable'>, 417: <class 'werkzeug.exceptions.ExpectationFailed'>, 418: <class 'werkzeug.exceptions.ImATeapot'>, 422: <class 'werkzeug.exceptions.UnprocessableEntity'>, 423: <class 'werkzeug.exceptions.Locked'>, 428: <class 'werkzeug.exceptions.PreconditionRequired'>, 429: <class 'werkzeug.exceptions.TooManyRequests'>, 431: <class 'werkzeug.exceptions.RequestHeaderFieldsTooLarge'>, 451: <class 'werkzeug.exceptions.UnavailableForLegalReasons'>, 500: <class 'werkzeug.exceptions.InternalServerError'>, 501: <class 'werkzeug.exceptions.NotImplemented'>, 502: <class 'werkzeug.exceptions.BadGateway'>, 503: <class 'werkzeug.exceptions.ServiceUnavailable'>, 504: <class 'werkzeug.exceptions.GatewayTimeout'>, 505: <class 'werkzeug.exceptions.HTTPVersionNotSupported'>}
1.2 使用方式二:传递一个json格式字符串
from flask import abort, jsonify @app.route("/") def index(): code = 50000 data = [{"data1": "lalallala", {"data2": "lolololo"}] json_data = jsonify({"code": code, "data": data}) abort(json_data) # 下面这条消息没法打印出来,由于上面abort函数已经终止了这个视图函数的运行。 print("我还在运行ing") return "Index Page"
这种方法至关于 return ,直接把传入abort中的数据返回到前端。
1.3 使用方式三:传递一个响应体
from flask import abort, Response @app.route("/") def index(): res = Response("Not Found", 404, {"name": "ttytty"}) # Response也能够返回响应体信息 abort(res) # 下面这条消息没法打印出来,由于上面abort函数已经终止了这个视图函数的运行。 print("我还在运行ing") return "Index Page"
直接返回给前端这个响应体。方式二和方式三很类似。
2. errorhandler
捕捉当前app或蓝图的状态码,而后能够进行自定义处理。
2.1 简单使用:
from flask import jsonify from . import admin @admin.errorhandler(404) def error_404(error): """这个handler能够catch住全部abort(404)以及找不到对应router的处理请求""" response = dict(status=0, message="404 Not Found") return jsonify(response), 404 @admin.errorhandler(Exception) def error_500(error): """这个handler能够catch住全部的abort(500)和raise exeception.""" response = dict(status=0, message="500 Error") return jsonify(response), 400 class MyError(Exception): """自定义错误类""" pass @admin.errorhandler(MyError) def MyErrorHandle(error): response = dict(status=0, message="400 Error") return jsonify(response), 400
2.2 封装成全局异常捕获处理:
- 自定义异常类(有须要的话)
from werkzeug.exceptions import HTTPException class EigenException(HTTPException): code = 500 eigen_code = 4000 description = 'Inner Server Error' class RequestError(EigenException): code = 400 class DataNotFound(RequestError): code = 404 eigen_code = 4004 description = 'Data Not Found' def __init__(self, message): self.description = '%s Not Found' % message class InvalidRequest(RequestError): eigen_code = 4005 description = 'Invalid Request URL' class MissingKey(RequestError): eigen_code = 4006 description = 'Missing Key' def __init__(self, key): self.description = 'Missing Key `%s`' % key
- 捕获异常并处理:
# 制定一个响应 def json_response(code, error, status_code): response = make_response(json.dumps(dict(code=code, error=error)), status_code) response.headers['Content-Type'] = 'application/json; charset=utf-8' return response # 异常捕获处理 @app.errorhandler(Exception) def handler_exception(e): if isinstance(e, 其余异常): code, status_code, error = 4000, 400, e.description elif isinstance(e, EigenException): code, status_code, error = e.eigen_code, e.code, e.description elif isinstance(e, HTTPException): code, status_code, error = e.code, e.code, e.description else: code, status_code, error = 5000, 500, '%s(%s)' % (e.__class__.__name__, str(e)) return json_response(code, error, status_code)
3. app_errorhandler
捕捉全局状态码,并进行自定制异常处理
在蓝本中编写错误处理程序有点不一样,若是使用errorhandler修饰器,那么只有蓝本中的错误才会触发。若是想注册全局的错误处理程序,要用app_errorhandler。
例如:
from bookapp import bokkapp @bookapp.app_errorhandler(Exception) def handler_exception(e): if isinstance(e, 其余异常): code, status_code, error = 4000, 400, e.description elif isinstance(e, EigenException): code, status_code, error = e.eigen_code, e.code, e.description elif isinstance(e, HTTPException): code, status_code, error = e.code, e.code, e.description else: code, status_code, error = 5000, 500, '%s(%s)' % (e.__class__.__name__, str(e)) response = dict(code=code, status=status_code, msg=error) return jsonify(response)
**注意: **当咱们不是使用的工厂模式建立app时,app.errorhandler(401),便可捕捉全局401状态;若使用了create_app方式建立app,则没法进行捕捉,若想捕捉,能够在蓝图中写,如admin.errorhandler(401),即捕捉admin蓝图下全部401状态码,admin.app_errorhandler(401),则是捕捉的全局的401状态码,即其余蓝图中的401状态,也会被捕捉,进行处理
参考文章: