[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狀態,也會被捕捉,進行處理
參考文章: