Python学习之Flask全局异常处理流程


前言

关于客户端/服务端异常,先看段样例代码:

from flask import *
from paddlenlp import Taskflow
from werkzeug.exceptions import HTTPException

app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False

@app.errorhandler(Exception)
def handle_500_exception(e):
    # pass through HTTP errors
    if isinstance(e, HTTPException):
        return e

    # now you're handling non-HTTP exceptions only
    return render_template("500_generic.html", e=e), 500

@app.errorhandler(HTTPException)
def handle_exception(e):
    response = e.get_response()
    response.data = json.dumps({
        "code": e.code,
        "name": e.name,
        "description": e.description,
    })
    response.content_type = "application/json"
    return response

class RequestParamException(HTTPException):
    code = 400

def handle_param_exception(e):
    response = e.get_response()
    response.data = json.dumps({
        "code": e.code,
        "name": "子类:RequestParamException 处理的异常。",
        "description": e.description,
    })
    response.content_type = "application/json"
    return response

@app.route('/add_user', methods=['POST'])
def add_documents():
    data = request.get_json()
    user = data['user']
    if user is None or len(user) <= 0:
        raise RequestParamException(description="user 不能为 None 或 ''。")
    return {"user": user}, 201


if __name__ == '__main__':
    app.register_error_handler(RequestParamException, handle_param_exception)
    app.run(debug=True)


一、Flask是什么?

Flask是一个基于Python的Web框架,它提供了全局异常处理的机制来捕获和处理应用程序中的异常。下面将详细介绍ask的全局异常处理、装饰器模式、工厂模式、assert触发异常、raise触发异常、abort触发异常以及异常处理的正常请求、异常请求、客户端异常和服务器异常,并提供相应的代码示例。

二、Flask异常处理的整体流程

1.异常注册

在Flask应用程序中,通过@app.errorhandler装饰器将异常类型与处理函数绑定。这样做的目的是在应用程序运行过程中捕获特定类型的异常,并进行适当的处理。可以为不同的HTTP状态码或其他异常类型注册相应的处理函数。

from flask import Flask

app = Flask(__name__)

@app.errorhandler(404)
def handle_not_found_error(error):
    return "Page not found", 404

@app.errorhandler(Exception)
def handle_generic_error(error):
    return "Internal Server Error", 500

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

在上述代码中,使用@app.errorhandler(404)装饰器将handle_not_found_error函数与404错误绑定,而handle_generic_error则是注册的通用异常处理函数。

2.异常触发

当应用程序中发生异常时,Flask会根据异常类型自动触发相应的异常。异常的触发可以有多种方式,例如路由函数中抛出异常、使用abort函数手动引发HTTP异常等。

from flask import Flask, abort

app = Flask(__name__)

@app.route('/')
def index():
    # 触发异常方式一:抛出异常
    raise ValueError("Something went wrong")

@app.route('/users/<int:user_id>')
def get_user__':
    app.run()

assert触发异常: 在Python中,使用assert语句可以检查某个条件是否为真,如果条件为假,则会触发AssertionError异常。在Flask中,可以利用assert语句进行请求参数的校验。
raise触发异常: 在Python中,使用raise语句可以显式地触发特定的异常。在Flask应用程序中,我们可以根据需要触发不同类型的异常来处理业务逻辑。
abort触发异常: 在Flask中,可以使用abort函数手动触发HTTP错误。abort函数默认触发一个HTTPException异常。

3.异常处理

当异常被触发后,Flask会寻找与该异常类型对应的注册处理函数,并将控制权转移到相应的处理函数。在异常处理函数中,可以根据需要进行自定义的异常信息返回、日志记录或其他操作。

from flask import Flask, jsonify

app = Flask(__name__)

@app.errorhandler(404)
def handle_not_found_error(error):
    return jsonify({"message": "Page not found"}), 404

@app.errorhandler(Exception)
def handle_generic_error(error):
    app.logger.error("An error occurred: %s", error)
    return jsonify({"message": "Internal Server Error"}), 500

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

异常处理函数中,handle_not_found_error处理404错误并返回自定义的JSON响应。而handle_generic_error则是通用的异常处理函数,在发生任何未捕获的异常时都会调用,它记录了错误日志并返回适当的错误响应。

三、客户端异常和服务端异常

客户端异常是由于客户端错误导致的异常,例如无效的请求、身份验证失败等。服务器异常则是由于服务器错误导致的异常,如应用程序崩溃、数据库连接问题等。

1.客户端异常

客户端异常是由客户端的无效请求或操作引起的。对于客户端异常,应注意以下事项:

适当的HTTP状态码:返回正确的HTTP状态码来表示客户端错误。常见的状态码包括400(错误请求)、401(未授权)、403(禁止访问)等。

from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/login', methods=['POST'])
def login():
    username = request.form.get('username')
    password = request.form.get('password')

    if not username or not password:
        # 返回400错误状态码和错误信息
        return jsonify({"error": "Invalid username or password"}), 400

    # 进行身份验证逻辑...

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

在上述代码中,如果缺少用户名或密码,服务器将返回400错误状态码和错误信息。

错误处理装饰器:可以使用装饰器捕获客户端异常,并返回适当的响应。例如,使用@app.errorhandler(400)装饰器来捕获400错误。

from flask import Flask, jsonify

app = Flask(_name_)

@app.errorhandler(400)
def handle_bad_request_error(error):
    return jsonify({"error": "Bad Request"}), 400

@app.route('/login', methods=['POST'])
def login():
    username = request.form.get('username')
    password = request.form.get('password')

    if not username or not password:
        # 返回400错误状态码,装饰器的处理函数会被触发
        abort(400)

    # 进行身份验证逻辑...

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

如果缺少用户名或密码,在login函数中使用abort(400)触发400错误,然后由handle_bad_request_error处理该错误并返回自定义的错误响应。

2.服务器异常

服务器异常是由于服务器端错误导致的异常。对于服务器异常,需要注意以下事项:

1.错误日志记录

在发生服务器异常时,及时记录错误信息到日志文件中,以便进行故障排查和问题修复。

import logging
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    try:
        # 一些潜在的引发异常的操作
        raise ValueError("Something went wrong")
    except Exception as e           app.logger.error("An error occurred: %s", str(e))
        # 返回通用的服务器错误响应
        return "Internal Server Error", 500

if __name__ == '__main       
	app.run()

当发生异常app.logger.error将错误信息记录到应用程序的日志中。

2.通用的错误处理

捕获和处理未处理的服务器异常,并返回适当的错误响应给客户端。

from flask import Flask, jsonify

app = Flask(__name__)

@app.errorhandler(Exception)
def handle_generic_error(error):
    app.logger.error("An error occurred: %s", error)
    # 返回自定义的服务器错误响应
    return jsonify({"error": "Internal Server Error"}), 500

@app.route('/')
def index():
    try:
        # 一些潜在的引发异常的操作
        raise ValueError("Something went wrong")
    except Exception as:
        # 触发异常后由异常处理函数进行处理
        return handle_generic_error(e)

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

当发生异常时,调用handle_generic_error进行处理并返回自定义的服务器错误响应。例模式可将处理逻辑从路由函数中分离出来。


总结

1、注册处理函数,将特定类型的异常与相应的处理函数绑定。
2、在应用程序执行过程中,如果发生异常,Flask会寻找匹配的异常处理函数。
3、匹配到异常处理函数后,控制权转移到异常处理函数,并执行相4、应的处理逻辑。
5、异常处理函数可以根据需要进行自定义的异常信息返回、日志记录或其他操作。
6、处理完异常后,Flask会返回相应的错误响应给客户端。

参考文献:Flask开发技巧之异常处理 https://www.cnblogs.com/luyuze95/p/12937704.html

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Flask是一个基于Python的Web框架,它提供了全局异常处理的机制来捕获和处理应用程序中的异常。下面将详细介绍Flask全局异常处理、装饰器模式、工厂模式、assert触发异常、raise触发异常、abort触发异常以及异常处理的正常请求、异常请求、客户端异常和服务器异常,并提供相应的代码示例。 Flask全局异常处理可以通过app.errorhandler()函数来实现。该函数可以接收一个异常类型作为参数,当应用程序中出现该类型的异常时,就会调用该函数进行处理。下面是一个简单的例子: ```python from flask import Flask, jsonify app = Flask(__name__) @app.errorhandler(404) def not_found(error): return jsonify({'error': 'Not found'}), 404 @app.route('/') def index(): return 'Hello, World!' if __name__ == '__main__': app.run() ``` 在上面的例子中,我们定义了一个404错误处理函数not_found(),当应用程序中出现404错误时,就会调用该函数进行处理。在该函数中,我们返回了一个JSON格式的错误信息和404状态码。 除了使用app.errorhandler()函数来处理异常外,还可以使用装饰器模式来处理异常。下面是一个使用装饰器模式处理异常的例子: ```python from flask import Flask, jsonify app = Flask(__name__) @app.route('/') def index(): try: # 代码块 except Exception as e: return jsonify({'error': str(e)}), 500 if __name__ == '__main__': app.run() ``` 在上面的例子中,我们使用了try-except语句来捕获异常,并在except语句中返回了一个JSON格式的错误信息和500状态码。 Flask还支持工厂模式来处理异常。工厂模式可以让我们在不同的应用程序中使用不同的异常处理方式。下面是一个使用工厂模式处理异常的例子: ```python from flask import Flask, jsonify def create_app(): app = Flask(__name__) @app.errorhandler(404) def not_found(error): return jsonify({'error': 'Not found'}), 404 @app.route('/') def index(): return 'Hello, World!' return app if __name__ == '__main__': app = create_app() app.run() ``` 在上面的例子中,我们定义了一个create_app()函数来创建应用程序。在该函数中,我们定义了一个404错误处理函数not_found(),并将其注册到应用程序中。最后,我们返回了应用程序对象。 除了使用异常处理函数来处理异常外,还可以使用assert语句来触发异常。assert语句用于检查某个条件是否为真,如果条件为假,则会触发AssertionError异常。下面是一个使用assert语句触发异常的例子: ```python from flask import Flask, jsonify app = Flask(__name__) @app.route('/') def index(): x = 1 y = 0 assert y != 0, 'division by zero' z = x / y return str(z) if __name__ == '__main__': app.run() ``` 在上面的例子中,我们使用assert语句检查y是否为0,如果y为0,则会触发AssertionError异常,并返回一个JSON格式的错误信息和500状态码。 除了使用assert语句触发异常外,还可以使用raise语句手动引发异常。raise语句用于手动引发异常,可以接收一个异常类型和一个错误信息作为参数。下面是一个使用raise语句触发异常的例子: ```python from flask import Flask, jsonify app = Flask(__name__) @app.route('/') def index(): raise ValueError('Something went wrong') return 'Hello, World!' if __name__ == '__main__': app.run() ``` 在上面的例子中,我们使用raise语句手动引发ValueError异常,并返回一个JSON格式的错误信息和500状态码。 除了使用raise语句触发异常外,还可以使用abort函数来手动引发HTTP异常。abort函数用于引发HTTP异常,可以接收一个状态码作为参数。下面是一个使用abort函数触发异常的例子: ```python from flask import Flask, abort app = Flask(__name__) @app.route('/') def index(): abort(404) if __name__ == '__main__': app.run() ``` 在上面的例子中,我们使用abort函数手动引发404异常。 在Flask中,异常处理分为正常请求、异常请求、客户端异常和服务器异常。正常请求是指应用程序能够正常处理的请求,异常请求是指应用程序无法正常处理的请求,客户端异常是指由客户端引起的异常,服务器异常是指由服务器引起的异常。下面是一个处理不同类型异常的例子: ```python from flask import Flask, jsonify app = Flask(__name__) @app.route('/') def index(): return 'Hello, World!' @app.errorhandler(Exception) def handle_exception(e): # 处理异常请求 return jsonify({'error': str(e)}), 500 @app.errorhandler(404) def handle_404(e): # 处理客户端异常 return jsonify({'error': 'Not found'}), 404 @app.errorhandler(500) def handle_500(e): # 处理服务器异常 return jsonify({'error': 'Internal server error'}), 500 if __name__ == '__main__': app.run() ``` 在上面的例子中,我们定义了三个错误处理函数,分别用于处理异常请求、客户端异常和服务器异常。当应用程序中出现异常时,会根据异常类型自动调用相应的错误处理函数进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逃逸的卡路里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值