JXCT Soil Sensor 7-in-1 v3.4.9 (June 2025)
Professional IoT soil monitoring system with ESP32, Modbus RTU, MQTT, and advanced compensation algorithms
Загрузка...
Поиск...
Не найдено
error_handlers.cpp
См. документацию.
5#include "../wifi_manager.h"
7
9{
10 // Обработчик 404 - страница не найдена
11 webServer.onNotFound(
12 []()
13 {
14 String uri = webServer.uri();
15 String method = webServer.method() == HTTP_GET ? "GET" : "POST";
16
17 logWebRequest(method, uri, webServer.client().remoteIP().toString());
18
19 logWarn("404 Not Found: %s %s", method.c_str(), uri.c_str());
20
21 String html = generateErrorPage(404, "Страница не найдена");
22 webServer.send(404, "text/html; charset=utf-8", html);
23 });
24
25 // Общий обработчик ошибок для внутренних ошибок сервера
26 // Примечание: ESP32 WebServer не имеет встроенного onError,
27 // поэтому ошибки 500 обрабатываются в конкретных маршрутах
28}
29
30bool validateConfigInput(bool checkRequired)
31{
32 // Валидация базовых полей
33 if (checkRequired)
34 {
35 // SSID всегда обязательно
36 if (!webServer.hasArg("ssid") || webServer.arg("ssid").length() == 0)
37 {
38 logWarn("Валидация: отсутствует SSID");
39 return false;
40 }
41
42 // В STA режиме проверяем дополнительные поля
44 {
45 // Если MQTT включен, проверяем обязательные поля
46 if (webServer.hasArg("mqtt_enabled"))
47 {
48 if (!webServer.hasArg("mqtt_server") || webServer.arg("mqtt_server").length() == 0)
49 {
50 logWarn("Валидация: MQTT включен, но отсутствует сервер");
51 return false;
52 }
53 }
54
55 // Если ThingSpeak включен, проверяем API ключ
56 if (webServer.hasArg("ts_enabled"))
57 {
58 if (!webServer.hasArg("ts_api_key") || webServer.arg("ts_api_key").length() == 0)
59 {
60 logWarn("Валидация: ThingSpeak включен, но отсутствует API ключ");
61 return false;
62 }
63 }
64 }
65 }
66
67 // Валидация форматов данных
68 if (webServer.hasArg("mqtt_port"))
69 {
70 int port = webServer.arg("mqtt_port").toInt();
71 if (port < 1 || port > 65535)
72 {
73 logWarn("Валидация: некорректный MQTT порт: %d", port);
74 return false;
75 }
76 }
77
78 if (webServer.hasArg("ntp_interval"))
79 {
80 int interval = webServer.arg("ntp_interval").toInt();
81 if (interval < 10000 || interval > 86400000)
82 { // от 10 сек до 24 часов
83 logWarn("Валидация: некорректный NTP интервал: %d", interval);
84 return false;
85 }
86 }
87
88 // Валидация интервалов датчика
89 if (webServer.hasArg("sensor_read"))
90 {
91 int interval = webServer.arg("sensor_read").toInt();
92 if (interval < 1000 || interval > 300000)
93 { // от 1 сек до 5 мин
94 logWarn("Валидация: некорректный интервал чтения датчика: %d", interval);
95 return false;
96 }
97 }
98
99 if (webServer.hasArg("mqtt_publish"))
100 {
101 int interval = webServer.arg("mqtt_publish").toInt();
102 if (interval < 1000 || interval > 3600000)
103 { // от 1 сек до 1 часа
104 logWarn("Валидация: некорректный интервал MQTT публикации: %d", interval);
105 return false;
106 }
107 }
108
109 if (webServer.hasArg("thingspeak_interval"))
110 {
111 int interval = webServer.arg("thingspeak_interval").toInt();
112 if (interval < 15000 || interval > 7200000)
113 { // от 15 сек до 2 часов (лимит ThingSpeak)
114 logWarn("Валидация: некорректный интервал ThingSpeak: %d", interval);
115 return false;
116 }
117 }
118
119 logDebug("Валидация конфигурации прошла успешно");
120 return true;
121}
122
123void handleUploadError(const String& error)
124{
125 logError("Ошибка загрузки файла: %s", error.c_str());
126
127 String html = generateErrorPage(400, "Ошибка загрузки файла: " + error);
128 webServer.send(400, "text/html; charset=utf-8", html);
129}
130
131bool isFeatureAvailable(const String& feature)
132{
133 // Большинство функций недоступны в AP режиме
135 {
136 // Разрешенные функции в AP режиме
137 if (feature == "main" || feature == "save" || feature == "status")
138 {
139 return true;
140 }
141 return false;
142 }
143 return true;
144}
145
146// Перегрузка без параметров для обратной совместимости
148{
149 return isFeatureAvailable("default");
150}
151
152void logWebRequest(const String& method, const String& uri, const String& clientIP)
153{
154 // Логирование только важных запросов, исключаем служебные
155 if (uri.startsWith("/sensor_json") || uri.startsWith(API_SENSOR))
156 {
157 // API запросы логируем на уровне DEBUG
158 logDebug("%s %s from %s", method.c_str(), uri.c_str(), clientIP.c_str());
159 }
160 else
161 {
162 // Обычные запросы на уровне INFO
163 logInfo("Web: %s %s from %s", method.c_str(), uri.c_str(), clientIP.c_str());
164 }
165}
166
172String generateValidationErrorResponse(const String& errorMsg)
173{
174 String content = "<h1>" UI_ICON_CONFIG " Настройки JXCT</h1>";
175 content += generateFormError(errorMsg);
176
177 // Здесь можно добавить восстановление формы с введенными данными
178 content +=
179 "<p><a href='javascript:history.back()' style='color: #4CAF50; text-decoration: none;'>← Назад к форме</a></p>";
180
181 return generateBasePage("Ошибка настроек", content, UI_ICON_CONFIG);
182}
183
188void handleCriticalError(const String& error)
189{
190 logError("Критическая ошибка веб-сервера: %s", error.c_str());
191
192 String html = generateErrorPage(500, "Внутренняя ошибка сервера: " + error);
193 webServer.send(500, "text/html; charset=utf-8", html);
194}
195
201bool isRouteAvailable(const String& uri)
202{
204 {
205 // В AP режиме доступны только базовые маршруты
206 return (uri == "/" || uri == "/save" || uri == "/status" || uri == "/reboot");
207 }
208 return true;
209}
210
215bool checkRouteAccess(const String& routeName, const String& icon)
216{
217 if (!isRouteAvailable(webServer.uri()))
218 {
219 String html = generateApModeUnavailablePage(routeName, icon);
220 webServer.send(403, "text/html; charset=utf-8", html);
221 return false;
222 }
223 return true;
224}
bool validateConfigInput(bool checkRequired)
Валидация входных данных конфигурации
Определения error_handlers.cpp:30
bool isRouteAvailable(const String &uri)
Проверка доступности маршрута в текущем режиме
Определения error_handlers.cpp:201
void logWebRequest(const String &method, const String &uri, const String &clientIP)
Логирование веб-запросов
Определения error_handlers.cpp:152
void handleCriticalError(const String &error)
Обработка критических ошибок сервера
Определения error_handlers.cpp:188
bool checkRouteAccess(const String &routeName, const String &icon)
Middleware для проверки доступности маршрута Используется в каждом маршруте, который недоступен в AP ...
Определения error_handlers.cpp:215
String generateValidationErrorResponse(const String &errorMsg)
Генерация HTML ответа с ошибкой валидации
Определения error_handlers.cpp:172
void handleUploadError(const String &error)
Обработка ошибок загрузки файлов
Определения error_handlers.cpp:123
void setupErrorHandlers()
Настройка обработчиков ошибок (404, 500, и т.
Определения error_handlers.cpp:8
bool isFeatureAvailable()
Проверка доступности функции в текущем режиме WiFi (без параметров)
Определения error_handlers.cpp:147
#define API_SENSOR
Определения jxct_strings.h:8
#define UI_ICON_CONFIG
Определения jxct_ui_system.h:46
void logDebug(const char *format,...)
Определения logger.cpp:112
void logWarn(const char *format,...)
Определения logger.cpp:78
void logError(const char *format,...)
Определения logger.cpp:61
void logInfo(const char *format,...)
Определения logger.cpp:95
Система логгирования с красивым форматированием
WebServer webServer
WiFiMode currentWiFiMode
Определения wifi_manager.cpp:26
String generateErrorPage(int errorCode, const String &errorMessage)
Генерация страницы ошибки
Определения web_templates.cpp:33
String generateApModeUnavailablePage(const String &title, const String &icon)
Генерация страницы "Недоступно в AP режиме".
Определения web_templates.cpp:175
String generateBasePage(const String &title, const String &content, const String &icon)
Генерация базовой HTML структуры с навигацией
Определения web_templates.cpp:24
String generateFormError(const String &message)
Генерация сообщения об ошибке в форме
Определения web_templates.cpp:164
@ AP
Определения wifi_manager.h:13
@ STA
Определения wifi_manager.h:14