Flask API 请求返回旧错误
Flask API requests returning old Errors
我正在开发一个将从云数据库读取数据的 Flask API。
我注意到错误处理中有一些奇怪的行为。
当我发出请求returns错误,然后再发出正确的请求时,错误json将在正确的请求中再次返回。但是只有在 body 中,API 状态代码是正确的(而且 flask 应用程序根本没有抛出错误,事实上它甚至似乎没有调用错误处理模块)。
如果我将错误从无效的 queryparam 请求更改为 404 请求,错误将在 json 中更改,并且返回的最新错误将在所有后续请求中持续存在,直到我重新运行应用程序。
我在我的应用程序中注册了一个错误处理模块:
from server.errorhandling.errors import InvalidQueryParameterError
from flask import Blueprint, jsonify, request
from server.common.jsonresponse import set_error_jsonresponse
import traceback
handle_errors = Blueprint('errorhandler', __name__)
@handle_errors.app_errorhandler(InvalidQueryParameterError)
def handle_notfound_error(error):
traceback.print_exc()
message = [str(x) for x in error.args]
status_code = 400
response = set_error_jsonresponse(message,error.__class__.__name__)
return jsonify(response), status_code
@handle_errors.app_errorhandler(404)
def handle_notfound_error(error):
traceback.print_exc()
message = [str(x) for x in error.args]
status_code = 404
response = set_error_jsonresponse(message,error.__class__.__name__)
return jsonify(response), status_code
正在我的应用程序中注册:
self.register_blueprint(errorhandler.handle_errors)
我有一个用于设置 json 响应的模块,“正常”成功响应代码和错误处理都使用该模块:
from flask import current_app,request,Blueprint
# - Static template for response json -
response_body = {
"domain": {
"datatype": {
"data": {
}
}
}
}
def set_jsonresponse(query_jobs):
for job in query_jobs:
response_tuple = queryjob_to_response_tuple(job)
response_data = response_tuple
response_obj = DataResponse(response_data)
response_body['domain']['datatype']['data'][get_data_entity_kvm(response_obj)[0]] = get_data_entity_kvm(response_obj)[1]
success_response_body = response_body
return success_response_body
def set_error_jsonresponse(message="An unexpected error has occurred.",errortype="InternalError"):
error_body = {
"error":{
"message":message,
"type":errortype
}
}
response_body['domain']['datatype'].update(error_body)
return response_body
其他一切似乎都按预期工作。
当我调试代码时,问题出现在我设置response_body的行中。但我不认为我如何在代码中设置响应是问题本身,我怀疑问题更多地与一些我还没有理解的background-storing响应数据有关。
虽然问题很相似,但我已经尝试过这里的答案:
API serving up old responses in flask
它不起作用。我试过发送 no-cache header 值并在我的应用程序中对它们进行硬编码。
我没有得到什么?
您正在将 response_body
定义为全局变量。
# - Static template for response json -
response_body = {
"domain": {
"datatype": {
"data": {
}
}
}
}
在 set_error_jsonresponse
调用中,您更新这个全局变量,然后 return 它:
response_body['domain']['datatype'].update(error_body)
此结构中存储的任何数据在后续请求中仍然存在,因为全局变量在 worker 的内存中。
我不确定 get_data_entity_kvm
是什么,但看起来您在 set_jsonresponse
函数中再次编辑全局,而没有删除之前添加的 error_body
。
response_body['domain']['datatype']['data'][get_data_entity_kvm(response_obj)[0]] = get_data_entity_kvm(response_obj)[1]
因此即使在后续的成功请求中,也会看到上次请求的错误消息。状态代码是正确的,因为它们是在处理函数中定义的。当您重新启动应用程序时,response_body
将设置回原来的状态。
对此的快速修复是 而不是 将 response_body
定义为全局。所以你可以有一个像这样的函数:
def get_response_body():
return {
"domain": {
"datatype": {
"data": {
}
}
}
}
然后在每个需要它的函数中,像这样:
def set_error_jsonresponse(message="An unexpected error has occurred.",errortype="InternalError"):
response_body = get_response_body()
# do something with that...
我还建议研究 Flask 部署文档,并了解 WSGI 服务器。在生产设置中,像 gunicorn
这样的 WSGI 服务器可能有多个同步工作线程。在该配置中,从该应用程序观察到的行为会更加奇怪:与您现在看到的相同,但不一致,因为后续请求可能由多个工作人员中的任何一个处理,每个工作人员都有自己的 response_body
全球。这是因为全局变量是 .
我正在开发一个将从云数据库读取数据的 Flask API。
我注意到错误处理中有一些奇怪的行为。
当我发出请求returns错误,然后再发出正确的请求时,错误json将在正确的请求中再次返回。但是只有在 body 中,API 状态代码是正确的(而且 flask 应用程序根本没有抛出错误,事实上它甚至似乎没有调用错误处理模块)。
如果我将错误从无效的 queryparam 请求更改为 404 请求,错误将在 json 中更改,并且返回的最新错误将在所有后续请求中持续存在,直到我重新运行应用程序。
我在我的应用程序中注册了一个错误处理模块:
from server.errorhandling.errors import InvalidQueryParameterError
from flask import Blueprint, jsonify, request
from server.common.jsonresponse import set_error_jsonresponse
import traceback
handle_errors = Blueprint('errorhandler', __name__)
@handle_errors.app_errorhandler(InvalidQueryParameterError)
def handle_notfound_error(error):
traceback.print_exc()
message = [str(x) for x in error.args]
status_code = 400
response = set_error_jsonresponse(message,error.__class__.__name__)
return jsonify(response), status_code
@handle_errors.app_errorhandler(404)
def handle_notfound_error(error):
traceback.print_exc()
message = [str(x) for x in error.args]
status_code = 404
response = set_error_jsonresponse(message,error.__class__.__name__)
return jsonify(response), status_code
正在我的应用程序中注册:
self.register_blueprint(errorhandler.handle_errors)
我有一个用于设置 json 响应的模块,“正常”成功响应代码和错误处理都使用该模块:
from flask import current_app,request,Blueprint
# - Static template for response json -
response_body = {
"domain": {
"datatype": {
"data": {
}
}
}
}
def set_jsonresponse(query_jobs):
for job in query_jobs:
response_tuple = queryjob_to_response_tuple(job)
response_data = response_tuple
response_obj = DataResponse(response_data)
response_body['domain']['datatype']['data'][get_data_entity_kvm(response_obj)[0]] = get_data_entity_kvm(response_obj)[1]
success_response_body = response_body
return success_response_body
def set_error_jsonresponse(message="An unexpected error has occurred.",errortype="InternalError"):
error_body = {
"error":{
"message":message,
"type":errortype
}
}
response_body['domain']['datatype'].update(error_body)
return response_body
其他一切似乎都按预期工作。 当我调试代码时,问题出现在我设置response_body的行中。但我不认为我如何在代码中设置响应是问题本身,我怀疑问题更多地与一些我还没有理解的background-storing响应数据有关。
虽然问题很相似,但我已经尝试过这里的答案: API serving up old responses in flask 它不起作用。我试过发送 no-cache header 值并在我的应用程序中对它们进行硬编码。
我没有得到什么?
您正在将 response_body
定义为全局变量。
# - Static template for response json -
response_body = {
"domain": {
"datatype": {
"data": {
}
}
}
}
在 set_error_jsonresponse
调用中,您更新这个全局变量,然后 return 它:
response_body['domain']['datatype'].update(error_body)
此结构中存储的任何数据在后续请求中仍然存在,因为全局变量在 worker 的内存中。
我不确定 get_data_entity_kvm
是什么,但看起来您在 set_jsonresponse
函数中再次编辑全局,而没有删除之前添加的 error_body
。
response_body['domain']['datatype']['data'][get_data_entity_kvm(response_obj)[0]] = get_data_entity_kvm(response_obj)[1]
因此即使在后续的成功请求中,也会看到上次请求的错误消息。状态代码是正确的,因为它们是在处理函数中定义的。当您重新启动应用程序时,response_body
将设置回原来的状态。
对此的快速修复是 而不是 将 response_body
定义为全局。所以你可以有一个像这样的函数:
def get_response_body():
return {
"domain": {
"datatype": {
"data": {
}
}
}
}
然后在每个需要它的函数中,像这样:
def set_error_jsonresponse(message="An unexpected error has occurred.",errortype="InternalError"):
response_body = get_response_body()
# do something with that...
我还建议研究 Flask 部署文档,并了解 WSGI 服务器。在生产设置中,像 gunicorn
这样的 WSGI 服务器可能有多个同步工作线程。在该配置中,从该应用程序观察到的行为会更加奇怪:与您现在看到的相同,但不一致,因为后续请求可能由多个工作人员中的任何一个处理,每个工作人员都有自己的 response_body
全球。这是因为全局变量是