# [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,返回的頁面:

在errorhandler裝飾後,返回的頁面:

若程式需要透過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)