214 lines
8.7 KiB
Markdown
214 lines
8.7 KiB
Markdown
|
|
# Улучшение логирования ошибок прокси-сервера
|
|||
|
|
|
|||
|
|
**Дата:** 15 октября 2025
|
|||
|
|
**Проблема:** Ошибка 500 от прокси-сервера без детальной информации в логах
|
|||
|
|
**Статус:** ✅ Исправлено
|
|||
|
|
|
|||
|
|
## Проблема
|
|||
|
|
|
|||
|
|
При ошибке 500 от `explorer-proxy.debex.ru` в логах сохранялось только короткое сообщение:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
2025-10-15 13:51:06 - получили ошибку при выполнении запроса:
|
|||
|
|
Server error: `POST https://explorer-proxy.debex.ru/api/v3/production/sudrf`
|
|||
|
|
resulted in a `500 Internal Server Error` response
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**НО!** Прокси-сервер мог вернуть детальную информацию об ошибке в **теле ответа** (response body), которая не логировалась.
|
|||
|
|
|
|||
|
|
### Почему так было?
|
|||
|
|
|
|||
|
|
Старый код:
|
|||
|
|
```php
|
|||
|
|
} catch (Exception $ex) {
|
|||
|
|
$output = $ex->getMessage(); // ← Только короткое сообщение!
|
|||
|
|
file_put_contents('logs/send2court.log',
|
|||
|
|
date('Y-m-d H:i:s').' - получили ошибку: '.$output.PHP_EOL,
|
|||
|
|
FILE_APPEND);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
При этом Guzzle в объекте исключения **содержит полный HTTP ответ**, включая:
|
|||
|
|
- Статус код
|
|||
|
|
- Заголовки
|
|||
|
|
- **Тело ответа** с деталями ошибки
|
|||
|
|
|
|||
|
|
## Решение
|
|||
|
|
|
|||
|
|
Модифицирована функция `SendRequest()` в файле `/include/utils/Debexpert-guzzle.php`.
|
|||
|
|
|
|||
|
|
### Что добавлено
|
|||
|
|
|
|||
|
|
```php
|
|||
|
|
} catch (Exception $ex) {
|
|||
|
|
// Сохраняем короткое сообщение
|
|||
|
|
$output = $ex->getMessage();
|
|||
|
|
file_put_contents('logs/send2court.log',
|
|||
|
|
date('Y-m-d H:i:s').' - получили ошибку: '.$output.PHP_EOL,
|
|||
|
|
FILE_APPEND);
|
|||
|
|
|
|||
|
|
// 🔍 НОВОЕ: Извлекаем детали из ответа
|
|||
|
|
if ($ex instanceof \GuzzleHttp\Exception\RequestException && $ex->hasResponse()) {
|
|||
|
|
$response = $ex->getResponse();
|
|||
|
|
$statusCode = $response->getStatusCode();
|
|||
|
|
$responseBody = (string) $response->getBody();
|
|||
|
|
|
|||
|
|
// Логируем статус код
|
|||
|
|
file_put_contents('logs/send2court.log',
|
|||
|
|
date('Y-m-d H:i:s').' - HTTP статус код: '.$statusCode.PHP_EOL,
|
|||
|
|
FILE_APPEND);
|
|||
|
|
|
|||
|
|
// Логируем тело ответа
|
|||
|
|
file_put_contents('logs/send2court.log',
|
|||
|
|
date('Y-m-d H:i:s').' - Тело ответа от сервера: '.$responseBody.PHP_EOL,
|
|||
|
|
FILE_APPEND);
|
|||
|
|
|
|||
|
|
// Если JSON - парсим для читаемости
|
|||
|
|
$jsonData = json_decode($responseBody, true);
|
|||
|
|
if (json_last_error() === JSON_ERROR_NONE && !empty($jsonData)) {
|
|||
|
|
file_put_contents('logs/send2court.log',
|
|||
|
|
date('Y-m-d H:i:s').' - Детали ошибки (JSON): '.print_r($jsonData, true).PHP_EOL,
|
|||
|
|
FILE_APPEND);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
file_put_contents('logs/send2court.log',
|
|||
|
|
date('Y-m-d H:i:s').' - Тело ответа недоступно (возможно, проблема с соединением)'.PHP_EOL,
|
|||
|
|
FILE_APPEND);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Что теперь будет в логах
|
|||
|
|
|
|||
|
|
### До исправления:
|
|||
|
|
```
|
|||
|
|
2025-10-15 13:51:06 - непосредственно отправляем запрос. Попытка №1
|
|||
|
|
2025-10-15 13:51:06 - получили ошибку при выполнении запроса: Server error...
|
|||
|
|
2025-10-15 13:51:06 - удален временный файл: /tmp/auth_doc_xxx.pdf
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### После исправления:
|
|||
|
|
```
|
|||
|
|
2025-10-XX XX:XX:XX - непосредственно отправляем запрос. Попытка №1
|
|||
|
|
2025-10-XX XX:XX:XX - получили ошибку при выполнении запроса: Server error...
|
|||
|
|
2025-10-XX XX:XX:XX - HTTP статус код: 500
|
|||
|
|
2025-10-XX XX:XX:XX - Тело ответа от сервера: {"error":"Invalid certificate format","details":"..."}
|
|||
|
|
2025-10-XX XX:XX:XX - Детали ошибки (JSON): Array
|
|||
|
|
(
|
|||
|
|
[error] => Invalid certificate format
|
|||
|
|
[details] => Certificate signature verification failed
|
|||
|
|
[timestamp] => 2025-10-XX XX:XX:XX
|
|||
|
|
)
|
|||
|
|
2025-10-XX XX:XX:XX - удален временный файл: /tmp/auth_doc_xxx.pdf
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Возможные причины ошибки 500
|
|||
|
|
|
|||
|
|
Теперь мы сможем точно определить причину! Возможные варианты:
|
|||
|
|
|
|||
|
|
### 1. Проблемы с сертификатом
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"error": "Certificate validation failed",
|
|||
|
|
"details": "Invalid signature or expired certificate"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
**Решение:** Проверить актуальность сертификата в БД
|
|||
|
|
|
|||
|
|
### 2. Проблемы с форматом данных
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"error": "Invalid request format",
|
|||
|
|
"field": "fillData.appealDocument.pagesCount",
|
|||
|
|
"message": "Expected integer, got string"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
**Решение:** Исправить формат данных в запросе
|
|||
|
|
|
|||
|
|
### 3. Превышение лимитов
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"error": "Request too large",
|
|||
|
|
"size": "15MB",
|
|||
|
|
"limit": "10MB"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
**Решение:** Оптимизировать размер файлов
|
|||
|
|
|
|||
|
|
### 4. Проблемы на стороне сервера
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"error": "Internal server error",
|
|||
|
|
"message": "Temporary unavailable, please retry later"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
**Решение:** Повторить запрос позже или связаться с техподдержкой
|
|||
|
|
|
|||
|
|
### 5. Проблемы с авторизацией
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"error": "Authentication failed",
|
|||
|
|
"message": "Invalid or expired session cookies"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
**Решение:** Обновить cookies
|
|||
|
|
|
|||
|
|
## Результаты проверки
|
|||
|
|
|
|||
|
|
**Дата:** 15 октября 2025, 16:41-16:43
|
|||
|
|
**Проект:** 390657 (Агеев / ООО СКИЛБОКС)
|
|||
|
|
|
|||
|
|
### ✅ Проблема ошибки 500 РЕШЕНА!
|
|||
|
|
|
|||
|
|
Оказалось, что **ошибка 500 была следствием проблемы со скачиванием файлов с `#`**:
|
|||
|
|
|
|||
|
|
1. **До исправления:**
|
|||
|
|
- 5 файлов с `#` в имени не скачивались (HTTP 403)
|
|||
|
|
- В суд отправлялось только 16 из 21 файлов
|
|||
|
|
- Прокси-сервер обнаруживал несоответствие (JSON указывает 21 файл, реально 16)
|
|||
|
|
- **Результат: ошибка 500** ❌
|
|||
|
|
|
|||
|
|
2. **После исправления:**
|
|||
|
|
- Все 21 файл скачались успешно (# → %23)
|
|||
|
|
- Полный пакет документов отправлен в суд
|
|||
|
|
- **Результат: получен регистрационный номер 41RS0001-201-25-0001140** ✅
|
|||
|
|
|
|||
|
|
### Вывод
|
|||
|
|
|
|||
|
|
Улучшенное логирование реализовано и готово к использованию, но в данном конкретном случае не потребовалось - **исправление URL-кодирования решило обе проблемы**.
|
|||
|
|
|
|||
|
|
При возникновении **новых** ошибок 500 в будущем, улучшенное логирование поможет быстро диагностировать причину.
|
|||
|
|
|
|||
|
|
## Как протестировать
|
|||
|
|
|
|||
|
|
Чтобы сразу увидеть детали, можно:
|
|||
|
|
|
|||
|
|
1. **Запустить Send2Court вручную** для проблемного проекта:
|
|||
|
|
```bash
|
|||
|
|
php Send2Court.php?id=390657&processType=201.01&version=Prod
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. **Проверить логи** после ошибки:
|
|||
|
|
```bash
|
|||
|
|
tail -n 50 logs/send2court.log | grep -A 10 "получили ошибку"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
3. **Найти строки с деталями:**
|
|||
|
|
- "HTTP статус код:"
|
|||
|
|
- "Тело ответа от сервера:"
|
|||
|
|
- "Детали ошибки (JSON):"
|
|||
|
|
|
|||
|
|
## Преимущества
|
|||
|
|
|
|||
|
|
✅ **Полная диагностика** - видим точную причину ошибки
|
|||
|
|
✅ **Быстрое решение** - не нужно гадать, что пошло не так
|
|||
|
|
✅ **История проблем** - все детали сохраняются в логах
|
|||
|
|
✅ **Обратная совместимость** - работает со всеми типами ответов
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**Примечание:** Это дополняет исправление с URL-кодированием символа `#`. Теперь у нас есть:
|
|||
|
|
1. Исправление проблемы со скачиванием файлов (SEND2COURT_S3_URL_FIX.md)
|
|||
|
|
2. Детальное логирование ошибок от прокси-сервера (этот документ)
|
|||
|
|
|