flask异常处理
1. flask exception
在view函数中,如果需要中断request,可以使用abort(500)或者直接raise exception。当然我们还需要返回一个出错信息给前端,所以需要定制一下ErrorHandler。
一般只需要两个handler即可,一个是404错误,一个是500一类的服务器端错误。当然也可以自定义错误。
1.1. abort/errorhandler
abort:flask中异常处理语句,功能类似于raise语句;触发abort后会中止视力方法,返回分发函数;abort参数需为http状态码的子集。
errorhandler:装饰器,注册异常处理函数,配合abort函数使用,根据状态码匹配,返回Response() 实例或者(string, status_code)。
from werkzeug.exceptions import abort
@app.route('/abort')
def view_abort():
abort(405) # 请求中断,返回状态码405
@app.errorhandler(405) # 处理中断,返回响应体
def err_handle(e):
return '错误404' + str(e), 405
# return Response('错误404' + str(e), 405) # 与上一行效果相同
1.3. 蓝图异常处理
蓝图也可以注册异常处理方法,可以注册蓝图级/全局级异常处理函数(仅装饰器方法名不同)。
具体见下方案例,不过不建议在蓝图中注册全局级异常处理函数。
# 非全局
@blue_t.errorhandler(405)
def err_405(e):
print('err_405')
return 'error 405 from blueprint blue_t'
# app_errorhandler()是全局的
@blue_t.app_errorhandler(405)
def err_404(e):
return 'blueprint error_405'
#return render_template('error/404.html')
案例
生产环境下一般将大部分异常隐藏,只返回500到前端。
下例即是将错误日志写入文件,前端返回500
from flask import jsonify, render_template
from flask import abort, current_app
from werkzeug.http import HTTP_STATUS_CODES
# 异常处理
def register_errors(app):
from werkzeug.exceptions import HTTPException
@app.errorhandler(404)
def page_not_found(error):
return render_template('error/404.html'), 404
@app.errorhandler(405)
def err_405(e):
# print('main:err_405')
return '错误405: ' + str(e), 405
@app.errorhandler(HTTPException) # 处理除上述异常以外的所有异常
def err_all(error):
current_app.logger_main.error(error, exc_info=True)
return Response(r'服务器错误', 500)
2. 总结
关于abort/errorhandler
flask在full_dispatch_request中处理请求,如果使用abort即为抛出异常,
接下来执行rv = self.handle_user_exception(e)
它会去注册的异常处理函数中根据e.code(abort的参数)匹配,并且优先在蓝图的异常处理函数中进行匹配
无论如何,最后的结果一定是Response() 实例或者(string, status_code)。
如果愿意的话,也可以直接在视图中 return Response('error 500', 500)
顶层app中的异常处理集中到函数中然后调用。
尽量不要在蓝图中声明全局异常处理。
对于异常可以由server仅返回状态码,nginx返回静态网页,以节约服务器资源。