# Запрос на анализ: XHR onerror («Сеть») при POST /upload с телом > 100KB **Дата:** 2026-06-17 **Версия:** v1.41 **ТОЛЬКО АНАЛИЗ. КОД НЕ ПРАВИТЬ.** --- ## Что поменялось в понимании После просмотра текущего кода причина выглядит уже не как `request.get_data()` сама по себе. Ветка `/upload` сейчас делает так: 1. читает всё тело через `request.get_data(as_text=True)` 2. выдёргивает `filename`, `data`, `cid` regex-ом 3. если `cid` пустой, синхронно создаёт контракт в PostgreSQL 4. затем синхронно вызывает `redis_client.push(...)` 5. только после этого возвращает `jsonify({"contract_id": ...})` Самое подозрительное место — именно синхронный Redis push в запросе, а не чтение тела. Если Redis/DNS/сеть внутри кластера тормозит или подвисает, клиент уже видит `xhr.onerror` как «Сеть», хотя тело запроса успело уйти целиком. --- ## Текущий код ```python # app.py raw = request.get_data(as_text=True) ... redis_client.push({"filename": filename, "b64": b64, "mime": mime, "cid": str(cid)}) return jsonify({"contract_id": str(cid)}) ``` ```python # redis_client.py _r = redis.Redis( host=os.getenv("REDIS_HOST", "redisk8s....svc.cluster.local"), port=int(os.getenv("REDIS_PORT", "6379")), password=os.getenv("REDIS_PASS", "..."), decode_responses=True, socket_connect_timeout=5, ) def push(task: dict): _get().rpush(UPLOAD_QUEUE, json.dumps(task, ensure_ascii=False)) ``` --- ## Локальная гипотеза `request.get_data()` не ломает соединение на 200KB. Запрос уже дошёл. Соединение рвётся или уходит в таймаут на этапе синхронного `rpush()` в Redis, либо на первом обращении к Redis-клиенту, если DNS/соединение внутри кластера нестабильны. Это объясняет, почему: - маленькие тела проходят чаще; - сервер иногда успевает обработать и записать лог; - `xhr.upload` показывает 100%, а затем приходит `onerror`; - `curl` даёт плавающий `HTTP:000` / `ReadTimeout`. --- ## Что надо проверить первым Самый дешёвый дискриминирующий тест — замерить время именно вокруг `redis_client.push()` и временно обойти его для `/upload`. Если ответ сразу стабилизируется, проблема подтверждается. Если нет, следующая точка проверки — внешний таймаут/обрыв на ingress или gunicorn, но по текущему коду Redis выглядит ближе всего к критическому узлу. --- ## Вывод В v1.40 сместили фокус с парсинга тела на более поздний синхронный шаг. Сам `get_data()` теперь выглядит не как корень проблемы, а как просто первая стадия запроса. Корневой кандидат — блокирующий `redis_client.push()` в обработчике `/upload`.