簡體   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