You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask查询Redis不存在键未返回404,反而返回200的问题求助

Redis透明代理Flask应用404状态码返回异常排查

问题描述

开发Redis透明代理的Python Flask应用时,查询Redis中不存在的键,预期返回404响应状态码,但实际始终返回200。

应用路由代码

from flask import Flask, request, jsonify
import redis 

app = Flask(__name__)

redis_client = redis.StrictRedis(host = 'localhost', port=6379, db=0)
@app.route('/get/<key>', methods= ['GET'])
def get_data(key):
    value = redis_client.get(key)
    if value:
        return jsonify({'key': key, 'value': value.decode('utf-8')})
    else:
        return jsonify({'message': 'Key not found'}, 404)
if __name__ == '__main__':
    app.run()

测试代码

import unittest
from flask import Flask, jsonify
import redis

from redis_proxy import app

class RedisProxyTest(unittest.TestCase):
    def setUp(self):
        self.app = app.test_client()
    def test_get_data(self):
        redis_client = redis.StrictRedis(host='localhost', port=6379, db=0)
        redis_client.set('test_key', 'test_value')
        response = self.app.get('/get/test_key')
        self.assertEqual(response.status_code, 200)
        expected_data = {'key': 'test_key', 'value': 'test_value'}
        self.assertEqual(response.get_json(), expected_data)

    def test_get_data_key_not_found(self):
        response = self.app.get('/get/xxx')
        print(response.data)
        print(response.status_code)
        self.assertEqual(response.status_code, 404)
        expected_data = {'message': 'Key not found'}
        self.assertEqual(response.get_json(), expected_data)
if __name__ == '__main__':
    unittest.main()

测试输出

python3 -m unittest redis_proxy_test.py
.b'[{"message":"Key not found"},404]\n'
200
F
======================================================================
FAIL: test_get_data_key_not_found (redis_proxy_test.RedisProxyTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/redis-proxy/redis_proxy_test.py", line 26, in test_get_data_key_not_found
    self.assertEqual(response.status_code, 404)
AssertionError: 200 != 404

----------------------------------------------------------------------
Ran 2 tests in 0.006s

FAILED (failures=1)

Redis验证结果

127.0.0.1:6379> GET xxx
(nil)

排查思路与解决方案

  1. 问题根源:从测试输出的response.data可以看到,404被包含在了JSON响应体中(返回内容为[{"message":"Key not found"},404]),而没有被设置为HTTP响应状态码。这是因为Flask的jsonify()函数仅接受需要序列化的JSON数据作为参数,直接将状态码作为第二个参数传入jsonify(),会被当成JSON数据的一部分处理,而非设置HTTP状态码。

  2. 修复方法:修改应用路由中else分支的返回语句,将状态码作为返回元组的第二个元素:

else:
    return jsonify({'message': 'Key not found'}), 404

这样Flask会将第一个值作为响应体,第二个值作为HTTP状态码返回,符合预期。

  1. 验证:修改后重新运行测试,test_get_data_key_not_found会返回404状态码,响应体为{"message":"Key not found"},测试通过。

内容的提问来源于stack exchange,提问作者Steven Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 01:14:52