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应用的错误处理更友好、更可控。

小夜