繁体   English   中英

Flask API 请求返回旧错误

[英]Flask API requests returning old Errors

我正在开发一个 Flask API 将从云数据库中读取数据。

我注意到我的错误处理中有一些奇怪的行为。

当我发出返回错误的请求,然后发出正确的请求时,错误 json 将在正确的请求中再次返回。 不过,仅在正文中,API 状态代码是正确的(并且 flask 应用程序根本没有抛出错误,实际上它甚至似乎都没有调用错误处理模块)。

如果我将错误从例如无效的查询参数请求更改为 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 的行中。 但我不认为我如何在代码中设置响应本身就是问题,我怀疑问题更多地与我尚未理解的响应数据的一些背景存储有关。

虽然问题很相似,但我在这里尝试了答案: API serving up old responses in flask而且它不起作用。 我已经尝试在我的应用程序中发送无缓存 header 值和硬编码它们。

我没有得到什么?

您将response_body定义为全局变量。

# - Static template for response json -
response_body = {
                        "domain": {
                            "datatype": {
                                "data": {
                                }
                            }
                        }
                    }

set_error_jsonresponse调用中,您更新此全局变量,然后将其返回:

response_body['domain']['datatype'].update(error_body)

存储在此结构中的任何数据在后续请求中仍然存在,因为全局变量位于 worker 的 memory 中。

我不确定get_data_entity_kvm是什么,但它看起来像在set_jsonresponse function 中您再次编辑全局,而不删除之前添加的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定义为全局。 所以你可以有一个 function 像:

def get_response_body():
    return {
        "domain": {
            "datatype": {
                "data": {
                }
            }
        }
    }

然后在需要它的每个 function 中,例如:

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副本全球的。 这是因为全局变量不是线程安全的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM