Flask錯誤處理:404、500錯誤與自定義響應

在Web開發中,用戶訪問不存在的頁面或服務器內部出錯是常有的事。如果直接返回系統默認的錯誤頁面(比如“404 Not Found”或“500 Internal Server Error”),不僅用戶體驗差,還可能讓用戶感到困惑。Flask提供了靈活的錯誤處理機制,能幫我們自定義這些錯誤響應,讓錯誤提示更友好、更符合項目需求。

Flask默認的錯誤響應

先簡單看一下Flask的默認錯誤行爲。我們寫一個最基礎的Flask應用:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
    return "歡迎來到首頁"

if __name__ == '__main__':
    app.run(debug=True)  # 調試模式下運行

運行這個應用後,訪問以下兩種情況:
1. 訪問不存在的URL(比如http://localhost:5000/abc):Flask會默認返回一個“404 Not Found”的純文本頁面,類似:

   404 Not Found
   The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
  1. 故意製造代碼錯誤(比如在視圖函數里寫1/0除零錯誤):Flask會返回“500 Internal Server Error”,並顯示詳細的錯誤堆棧(調試模式下),但普通用戶看不懂這些信息。

默認錯誤頁面雖然簡單,但對於大多數項目來說不夠友好,我們需要自定義這些響應。

@app.errorhandler自定義錯誤響應

Flask通過@app.errorhandler裝飾器,允許我們爲特定錯誤碼(如404、500)定義自定義處理邏輯。裝飾器接收一個錯誤碼作爲參數,然後在函數里返回自定義的內容(HTML、JSON等)。

1. 自定義404錯誤頁面

當用戶訪問不存在的頁面時,返回一個友好的提示,比如“頁面飛走了~”,並引導用戶返回首頁。示例代碼:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
    return "歡迎來到首頁"

# 處理404錯誤
@app.errorhandler(404)
def page_not_found(error):
    # 返回自定義HTML內容,狀態碼設爲404
    return '''
    <!DOCTYPE html>
    <html>
    <head>
        <title>頁面不見了</title>
        <style>
            body { text-align: center; margin-top: 50px; font-family: sans-serif; }
            h1 { color: #ff6b6b; }
            a { color: #4ecdc4; text-decoration: none; }
        </style>
    </head>
    <body>
        <h1>哎呀,頁面不見了!</h1>
        <p>你找的頁面可能被外星人“借走”了,或者你輸錯了網址~</p>
        <a href="/">返回首頁</a>
    </body>
    </html>
    ''', 404  # 必須顯式返回404狀態碼,否則Flask會認爲是成功響應

if __name__ == '__main__':
    app.run(debug=False)  # 注意:debug=True時會顯示詳細錯誤頁面,生產環境建議關閉debug

訪問http://localhost:5000/abc,就能看到自定義的404頁面了。

2. 自定義500錯誤頁面

當服務器內部出錯(比如代碼異常)時,返回“服務器開小差”的提示。示例:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
    return "歡迎來到首頁"

@app.route('/error')
def cause_error():
    # 故意製造錯誤(除零錯誤)
    return 1 / 0  # 觸發500錯誤

# 處理500錯誤
@app.errorhandler(500)
def server_error(error):
    return '''
    <!DOCTYPE html>
    <html>
    <head>
        <title>服務器出錯了</title>
        <style>
            body { text-align: center; margin-top: 50px; font-family: sans-serif; }
            h1 { color: #ffc857; }
            p { color: #6a6a6a; }
            a { color: #4ecdc4; text-decoration: none; }
        </style>
    </head>
    <body>
        <h1>服務器開小差了~</h1>
        <p>很抱歉,系統在處理請求時遇到了問題,請稍後再試!</p>
        <a href="/">返回首頁</a>
    </body>
    </html>
    ''', 500

if __name__ == '__main__':
    app.run(debug=False)

訪問http://localhost:5000/error,就能看到自定義的500錯誤頁面。

3. 返回JSON格式的錯誤響應

如果項目是API接口,可能需要返回JSON格式的錯誤信息。Flask支持直接返回JSON,只需導入jsonify

from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/api/user/<int:user_id>')
def get_user(user_id):
    if user_id not in [1, 2, 3]:
        # 返回404 JSON錯誤
        return jsonify({
            "status": "error",
            "code": 404,
            "message": "用戶不存在"
        }), 404
    return jsonify({"id": user_id, "name": "用戶"})

if __name__ == '__main__':
    app.run(debug=False)

訪問不存在的用戶ID(比如/api/user/99),會返回JSON格式的錯誤提示:

{
  "status": "error",
  "code": 404,
  "message": "用戶不存在"
}

總結

Flask的錯誤處理核心是@app.errorhandler裝飾器,通過它可以爲不同錯誤碼(404、500等)定義自定義響應。自定義錯誤頁面能提升用戶體驗,避免用戶因“看不懂的錯誤提示”而流失。對於簡單場景,直接返回HTML字符串即可;對於複雜項目,可結合模板或JSON格式,甚至記錄錯誤日誌輔助調試。

通過以上方法,你可以輕鬆讓Flask應用的錯誤處理更友好、更可控。

小夜