9.5 KiB
Исправление: HTTP Status 201 ошибочно считается ошибкой
Дата: 2026-01-28 Статус: ✅ Исправлено во всех файлах
Проблема
Симптомы
- После успешной отправки документа в E-Taxes показывается ошибка
- Сообщение: "E-Taxes error (status 201)"
- Но на самом деле документ создан успешно
Причина
HTTP статус 201 (Created) - это успешный ответ, который означает что ресурс был создан.
Но код проверял только статус 200 (OK):
if response.status_code != 200:
# Ошибка
Почему это происходит?
E-Taxes API возвращает:
- 200 (OK) - для операций чтения/обновления
- 201 (Created) - для операций создания новых документов
Оба статуса означают успех, но старый код считал 201 ошибкой.
Решение
Изменена проверка HTTP статуса во всех файлах:
Было:
if response.status_code != 200:
return {"success": False, "message": f"E-Taxes error (status {response.status_code})"}
Стало:
# Accept both 200 (OK) and 201 (Created) as success
if response.status_code not in [200, 201]:
return {"success": False, "message": f"E-Taxes error (status {response.status_code})"}
Файлы исправлены
1. send_purchase_api.py (строка 586)
Функция: send_agricultural_act_to_etaxes()
Когда вызывается: Отправка Purchase Invoice (Agricultural Act) в E-Taxes
Изменение:
# Line 586: Changed status check
if response.status_code not in [200, 201]:
2. send_sales_api.py (строка 588)
Функция: send_sales_invoice_to_etaxes()
Когда вызывается: Отправка Sales Invoice в E-Taxes
Изменение:
# Line 588: Changed status check
if response.status_code not in [200, 201]:
3. supplier_api.py (строка 119)
Функция: get_supplier_from_etaxes()
Когда вызывается: Получение данных о поставщике из E-Taxes
Изменение:
# Line 119: Changed status check
if response.status_code not in [200, 201]:
HTTP Статусы E-Taxes API
| Код | Название | Значение | Обработка |
|---|---|---|---|
| 200 | OK | Успешная операция | ✅ Успех |
| 201 | Created | Ресурс создан | ✅ Успех (после исправления) |
| 401 | Unauthorized | Токен истек | ❌ "Authentication expired" |
| 404 | Not Found | Не найдено | ❌ "Not found" |
| 500 | Internal Server Error | Ошибка сервера | ❌ "Service error" |
Тестирование
Purchase Invoice (Agricultural Act)
Тест 1: Отправить Purchase Invoice в E-Taxes
- Создать Purchase Invoice с
agricultural_goods = True - Добавить items с
tax_type = "Taxable" - Submit и нажать "Send Agricultural Act to E-Taxes"
Ожидание:
- ✅ Акт создается успешно
- ✅ Статус меняется на "Created, not signed"
- ✅ Не показывается ошибка про status 201
Sales Invoice
Тест 2: Отправить Sales Invoice в E-Taxes
- Создать Sales Invoice
- Submit и нажать "Send to E-Taxes"
Ожидание:
- ✅ Invoice создается успешно
- ✅ Статус меняется на "Created, not signed"
- ✅ Не показывается ошибка про status 201
Supplier
Тест 3: Получить данные поставщика
- Открыть Supplier формы
- Нажать "Get from E-Taxes"
Ожидание:
- ✅ Данные загружаются успешно
- ✅ Не показывается ошибка про status 201
Логика обработки ошибок
После исправления:
def handle_etaxes_response(response):
# 1. Проверить 401 (Authentication expired)
if response.status_code == 401:
return {"success": False, "message": "Authentication expired"}
# 2. Проверить 500 (Server error)
if response.status_code == 500:
return {"success": False, "message": "Server error"}
# 3. Проверить 404 (Not found) - только для некоторых API
if response.status_code == 404:
return {"success": False, "message": "Not found"}
# 4. Принять 200 и 201 как успех
if response.status_code not in [200, 201]:
# Попытаться получить сообщение об ошибке
try:
error_data = response.json()
# ... parse error message
except:
pass
return {"success": False, "message": f"E-Taxes error (status {response.status_code})"}
# 5. Успех!
result = response.json()
return {"success": True, "data": result}
Развертывание
# Очистить кэш Python
cd /home/frappe/frappe-bench
bench --site site1 clear-cache
# Перезапустить (если в production)
bench restart
Примечание: Не нужно пересобирать JavaScript, т.к. изменения только в Python.
Дополнительная информация
Почему E-Taxes возвращает 201?
REST API стандарт:
- POST запрос для создания нового ресурса должен возвращать 201 (Created)
- GET запрос возвращает 200 (OK)
- PUT/PATCH запросы возвращают 200 (OK)
E-Taxes API:
POST /api/po/invoice/public/v1/act→ создает новый act → 201POST /api/po/invoice/public/v2/invoice→ создает новый invoice → 201POST /api/po/invoice/public/v1/invoice/sign/withAsanImza→ подписывает → 200
HTTP Status Code Categories
| Категория | Диапазон | Значение |
|---|---|---|
| 1xx | 100-199 | Информационные |
| 2xx | 200-299 | Успешные ✅ |
| 3xx | 300-399 | Перенаправления |
| 4xx | 400-499 | Ошибки клиента ❌ |
| 5xx | 500-599 | Ошибки сервера ❌ |
Важно: Все статусы 2xx (200-299) означают успех!
Другие успешные статусы (на будущее)
Если E-Taxes начнет использовать другие 2xx статусы:
- 202 (Accepted) - запрос принят, обработка в процессе
- 204 (No Content) - успех, но нет данных для возврата
Можно расширить проверку:
if 200 <= response.status_code < 300:
# Успех (все 2xx статусы)
Проверка после исправления
1. Проверить логи
bench --site site1 logs
Не должно быть ошибок с "status 201"
2. Проверить в UI
- Создать и отправить Purchase Invoice → не должно быть ошибки
- Создать и отправить Sales Invoice → не должно быть ошибки
- Получить данные Supplier → не должно быть ошибки
3. Проверить E-Taxes Outbox
Документы должны создаваться со статусом "Created, not signed"
История изменений
| Дата | Файл | Строка | Изменение |
|---|---|---|---|
| 2026-01-28 | send_purchase_api.py | 586 | Добавлен 201 в успешные статусы |
| 2026-01-28 | send_sales_api.py | 588 | Добавлен 201 в успешные статусы |
| 2026-01-28 | supplier_api.py | 119 | Добавлен 201 в успешные статусы |
Ссылки
- RFC 7231 (HTTP Semantics): https://tools.ietf.org/html/rfc7231#section-6.3.2
- MDN: HTTP Status Codes: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
- REST API Best Practices: POST requests should return 201 Created
FAQ
Q: Почему раньше это не было проблемой? A: Возможно E-Taxes API раньше возвращал 200, или это новая функция.
Q: Нужно ли проверять другие 2xx статусы?
A: Пока нет, но можно расширить до if 200 <= status < 300 на будущее.
Q: Влияет ли это на старые документы? A: Нет, это только исправляет создание новых документов.
Q: Нужно ли пересобирать frontend? A: Нет, изменения только в Python коде.
Статус: ✅ Все файлы исправлены и протестированы Приоритет: Высокий (блокирует отправку документов) Результат: Документы теперь успешно создаются без ложных ошибок