# [Flask]Request的中斷和錯誤處理 ###### tags: `python` `flask` :::info * flask中的異常處理語句,功能類似於python中raise語句,只要觸發abort,後面的代碼不會執行,abort只能拋出符合http協議的異常狀態碼,不同於return可以返回自定義狀態碼。 * errorhandler裝飾器是配合abort函數使用的,為了進一步提升用戶體驗,他接收的是abort函數拋出的異常狀態碼,自定義錯誤頁面和信息。 ::: 使用abort(500)或直接raise exception,並且返回錯誤訊息給前端,所以需要制定ErrorHandler。一般只需要兩個handler,一個是404錯誤,另一個是500伺服器錯誤。(或是自定義錯誤) 發生404或500錯誤,會返回一個Json對象給請求端。 ```python= from flask import jsonify from . import main @main.errorhandler(404) def error_404(error): """这个handler可以catch住所有abort(404)以及找不到对应router的处理请求""" response = dict(status=0, message="404 Not Found") return jsonify(response), 404 @main.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 @main.errorhandler(MyError) def MyErrorHandle(error): response = dict(status=0, message="400 Error") return jsonify(response), 400 ``` 如果使用errorhandler修飾器,那麼只有藍本中的錯誤才會觸發。如果想註冊全局的錯誤處理程序,要用app_errorhandler。 ```python= from . import auth @auth.app_errorhandler(404) def error_404(error): response = dict(status=0, message="404 Not Found") return jsonify(response), 404 ``` 範例程式碼 ```python= from flask import Flask,abort app = Flask(__name__) @app.route('/') def index(): abort(404) return 'hello world' @app.errorhandler(404) def err_handler(e): return '您访问的页面走丢了,请访问***页面。' @app.errorhandler(Exception) def error_handle(e): response = {'error_code': e.error_code, 'error_message': e.error_message, 'Status': e.status} return jsonify(response), e.code if __name__ == '__main__': app.run(debug=True) ``` 如果沒有errorhandler,返回的頁面: ![](https://img-blog.csdnimg.cn/20181113200141727.png) 在errorhandler裝飾後,返回的頁面: ![](https://img-blog.csdnimg.cn/20181113200700251.png) 若程式需要透過try-except包裝且except一律返回InternalError,則try內所執行的raise會被InternalError覆蓋掉,所以任何400錯誤要寫在try-except之前! ```python= @app.route('/') def index(): for i in range(10): print("out try!") raise InvalidParameterValue() try: for i in range(10): print("in try!") raise InvalidParameterValue() except: raise InternalError() return 'hello world' ===output=== out try! (並觸發InvalidParameterValue) ``` 或是指定該例外進行抓取 ```python= @app.route('/') def index(): try: print("RUN") for i in range(10): print("in try!") raise InvalidParameterValue() except InvalidParameterValue as e: raise InvalidParameterValue() except: raise InternalError() return 'hello world' ===output=== RUN in try! (並觸發InvalidParameterValue) ``` ## 參考 [【Flask】Request的中断和ErrorHandler](https://blog.csdn.net/yannanxiu/article/details/52137781) [【Flask】abort和@errorhandler装饰器,自定义错误页面](https://blog.csdn.net/mydistance/article/details/84034771)