博客 / 詳情

返回

Flask筆記四之異常處理

本文首發於公眾號:Hunter後端

原文鏈接:Flask筆記四之異常處理

在系統運行中,有時候需要處理報錯異常。

異常的來源可能是系統在運行中的報錯,比如錯誤的運算的有 1/0 這種等,還有的是訪問了不存在接口,又或者,我們在查驗接口參數的時候,發現沒有傳必傳參數,需要手動觸發一個報錯等。

這裏就介紹如何在 Flask 中進行異常處理。

本篇筆記的代碼都已經提交到 github 上,可使用下面的操作獲取代碼:

git clone https://github.com/x1204604036/flask_backend.git

1、異常處理示例

這裏以請求的接口不存在為示例介紹一下異常處理流程。

處理一個異常,需要先對指定的異常進行註冊,對於請求接口不存在這種請求相關的異常,Flask 裏定義了一個 HTTPException 異常對其進行處理

這裏我們在 app/ 下創建一個文件夾 utils,再創建一個文件 exception_handler.py:

# app/utils/exception_handler.py

from werkzeug.exceptions import HTTPException
from flask import jsonify

def init_error_exception(app):

    @app.errorhandler(HTTPException)
    def handler_http_exception(exception):
        print(exception)
        return jsonify({"code": -1, "msg": exception.description}), exception.code

這裏創建了一個異常處理的函數,通過 @app.errorhandler(HTTPException) 的方式註冊,在 app/__init__.py 中引入:

from flask import Flask
from app.utils.exception_handler import init_error_exception

def create_app():
    app = Flask(__name__)

    init_error_exception(app)

    return app

flask.jsonify 用來返回 json 數據給客户端,後面跟着的是 HTTP 的 status code,就是 200,500 那些表示請求狀態的的狀態碼

這裏我們用 postman 請求一個不存在的接口,就可以看到返回的信息如下:

{
    "code": -1,
    "msg": "The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again."
}

status code 是 404,表示接口不存在

這樣,關於 HTTP 請求的異常處理就從註冊,到觸發,到返回結果完成了一個閉環。

2、其他異常處理

除了上面的請求異常,可能還有一些異常,比如我們在接口裏進行了 1/0 等不合法的運算,為了捕捉這種報錯,我們可以如下操作:

ERROR_HTTP_CODE = 417


def init_error_exception(app):
    @app.errorhandler(Exception)
    def server_exception(exception):
        print(exception)
        return jsonify({"code": -1, "msg": "內部錯誤"}), ERROR_HTTP_CODE

這樣,在系統裏發生異常異常之後,就會被捕捉,返回給客户端 內部錯誤 的信息

還有一些時候,舉個例子,比如在接口裏,客户端沒有傳來一些必傳的參數,我們可以手動觸發一個報錯,自定義報錯信息和HTTP狀態碼,可以如下這樣操作:

class UserException(Exception):
    def __init__(self, code=-1, msg="error", http_code=417):
        self.code = code
        self.msg = msg
        self.http_code = http_code

def init_error_exception(app):
    @app.errorhandler(UserException)
    def user_exception(exception):
        print(exception)
        return jsonify({"code": exception.code, "msg": exception.msg}), exception.http_code

然後我們在接口裏這樣調用觸發異常:

raise UserException(msg="手動測試error", http_code=417)

我們可以傳入 code,msg 和 http_code 參數,用於返回給前端

以上這些介紹的都是異常的處理,還可以在處理異常的時候打印日誌,用於記錄報錯的信息,這個我們後面介紹日誌的時候再介紹。

3、代碼總覽

以下給出前面介紹的三種異常處理的代碼:

# app/utils/exception_handler.py

from werkzeug.exceptions import HTTPException
from flask import jsonify


ERROR_HTTP_CODE = 417


class UserException(Exception):
    def __init__(self, code=-1, msg="error", http_code=417):
        self.code = code
        self.msg = msg
        self.http_code = http_code

def init_error_exception(app):
    @app.errorhandler(HTTPException)
    def handler_http_exception(exception):
        print(exception)
        return jsonify({"code": -1, "msg": exception.description}), exception.code

    @app.errorhandler(Exception)
    def server_exception(exception):
        print(exception)
        return jsonify({"code": -1, "msg": "內部錯誤"}), ERROR_HTTP_CODE


    @app.errorhandler(UserException)
    def user_exception(exception):
        print(exception)
        return jsonify({"code": exception.code, "msg": exception.msg}), exception.http_code

記得要在 app/__init__.py 中引入初始化處理哦

如果想獲取更多後端相關文章,可掃碼關注閲讀:

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.