From 980e847ccb9b062816887f81da25c79c41457eca Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Thu, 4 Apr 2024 20:43:07 +0200 Subject: [PATCH] Feature: Check for out of memory situations when sending json responses Also shows a nice message in the frontend if an internal error occours --- include/WebApi.h | 1 + include/WebApi_errors.h | 1 + src/WebApi.cpp | 27 +++++++++-- src/WebApi_config.cpp | 12 ++--- src/WebApi_device.cpp | 12 ++--- src/WebApi_devinfo.cpp | 3 +- src/WebApi_dtu.cpp | 27 ++++------- src/WebApi_eventlog.cpp | 3 +- src/WebApi_gridprofile.cpp | 6 +-- src/WebApi_inverter.cpp | 51 +++++++------------- src/WebApi_limit.cpp | 21 +++------ src/WebApi_maintenance.cpp | 9 ++-- src/WebApi_mqtt.cpp | 60 ++++++++---------------- src/WebApi_network.cpp | 39 +++++---------- src/WebApi_ntp.cpp | 48 +++++++------------ src/WebApi_power.cpp | 15 ++---- src/WebApi_security.cpp | 15 ++---- src/WebApi_sysstatus.cpp | 3 +- src/WebApi_ws_live.cpp | 7 +-- webapp/src/locales/de.json | 3 ++ webapp/src/locales/en.json | 3 ++ webapp/src/locales/fr.json | 3 ++ webapp/src/router/index.ts | 8 +++- webapp/src/utils/authentication.ts | 3 +- webapp/src/views/ErrorView.vue | 18 +++++++ webapp/src/views/FirmwareUpgradeView.vue | 2 +- 26 files changed, 171 insertions(+), 229 deletions(-) create mode 100644 webapp/src/views/ErrorView.vue diff --git a/include/WebApi.h b/include/WebApi.h index b4c499833..14eddc313 100644 --- a/include/WebApi.h +++ b/include/WebApi.h @@ -39,6 +39,7 @@ class WebApiClass { static void writeConfig(JsonVariant& retMsg, const WebApiError code = WebApiError::GenericSuccess, const String& message = "Settings saved!"); static bool parseRequestData(AsyncWebServerRequest* request, AsyncJsonResponse* response, JsonDocument& json_document); + static bool sendJsonResponse(AsyncWebServerRequest* request, AsyncJsonResponse* response, const char* function, const uint16_t line); private: AsyncWebServer _server; diff --git a/include/WebApi_errors.h b/include/WebApi_errors.h index 675419d72..97d61b220 100644 --- a/include/WebApi_errors.h +++ b/include/WebApi_errors.h @@ -9,6 +9,7 @@ enum WebApiError { GenericParseError, GenericValueMissing, GenericWriteFailed, + GenericInternalServerError, DtuBase = 2000, DtuSerialZero, diff --git a/src/WebApi.cpp b/src/WebApi.cpp index 04821d7e1..bd59bd3eb 100644 --- a/src/WebApi.cpp +++ b/src/WebApi.cpp @@ -4,6 +4,7 @@ */ #include "WebApi.h" #include "Configuration.h" +#include "MessageOutput.h" #include "defaults.h" #include @@ -93,8 +94,7 @@ bool WebApiClass::parseRequestData(AsyncWebServerRequest* request, AsyncJsonResp if (!request->hasParam("data", true)) { retMsg["message"] = "No values found!"; retMsg["code"] = WebApiError::GenericNoValueFound; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return false; } @@ -103,12 +103,31 @@ bool WebApiClass::parseRequestData(AsyncWebServerRequest* request, AsyncJsonResp if (error) { retMsg["message"] = "Failed to parse data!"; retMsg["code"] = WebApiError::GenericParseError; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return false; } return true; } +bool WebApiClass::sendJsonResponse(AsyncWebServerRequest* request, AsyncJsonResponse* response, const char* function, const uint16_t line) +{ + bool ret_val = true; + if (response->overflowed()) { + auto& root = response->getRoot(); + + root.clear(); + root["message"] = String("500 Internal Server Error: ") + function + ", " + line; + root["code"] = WebApiError::GenericInternalServerError; + root["type"] = "danger"; + response->setCode(500); + MessageOutput.printf("WebResponse failed: %s, %d\r\n", function, line); + ret_val = false; + } + + response->setLength(); + request->send(response); + return ret_val; +} + WebApiClass WebApi; diff --git a/src/WebApi_config.cpp b/src/WebApi_config.cpp index 99a539edc..a67be42fa 100644 --- a/src/WebApi_config.cpp +++ b/src/WebApi_config.cpp @@ -63,16 +63,14 @@ void WebApiConfigClass::onConfigDelete(AsyncWebServerRequest* request) if (!(root.containsKey("delete"))) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } if (root["delete"].as() == false) { retMsg["message"] = "Not deleted anything!"; retMsg["code"] = WebApiError::ConfigNotDeleted; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -80,8 +78,7 @@ void WebApiConfigClass::onConfigDelete(AsyncWebServerRequest* request) retMsg["message"] = "Configuration resettet. Rebooting now..."; retMsg["code"] = WebApiError::ConfigSuccess; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); Utils::removeAllFiles(); Utils::restartDtu(); @@ -110,8 +107,7 @@ void WebApiConfigClass::onConfigListGet(AsyncWebServerRequest* request) } file.close(); - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } void WebApiConfigClass::onConfigUploadFinish(AsyncWebServerRequest* request) diff --git a/src/WebApi_device.cpp b/src/WebApi_device.cpp index 421f9456e..078d5b4a1 100644 --- a/src/WebApi_device.cpp +++ b/src/WebApi_device.cpp @@ -86,8 +86,7 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request) led["brightness"] = config.Led_Single[i].Brightness; } - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } void WebApiDeviceClass::onDeviceAdminPost(AsyncWebServerRequest* request) @@ -108,8 +107,7 @@ void WebApiDeviceClass::onDeviceAdminPost(AsyncWebServerRequest* request) || root.containsKey("display"))) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -117,8 +115,7 @@ void WebApiDeviceClass::onDeviceAdminPost(AsyncWebServerRequest* request) retMsg["message"] = "Pin mapping must between 1 and " STR(DEV_MAX_MAPPING_NAME_STRLEN) " characters long!"; retMsg["code"] = WebApiError::HardwarePinMappingLength; retMsg["param"]["max"] = DEV_MAX_MAPPING_NAME_STRLEN; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -149,8 +146,7 @@ void WebApiDeviceClass::onDeviceAdminPost(AsyncWebServerRequest* request) WebApi.writeConfig(retMsg); - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); if (performRestart) { Utils::restartDtu(); diff --git a/src/WebApi_devinfo.cpp b/src/WebApi_devinfo.cpp index 212a7f7d5..68f3396b0 100644 --- a/src/WebApi_devinfo.cpp +++ b/src/WebApi_devinfo.cpp @@ -43,6 +43,5 @@ void WebApiDevInfoClass::onDevInfoStatus(AsyncWebServerRequest* request) root["fw_build_datetime"] = inv->DevInfo()->getFwBuildDateTimeStr(); } - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } diff --git a/src/WebApi_dtu.cpp b/src/WebApi_dtu.cpp index a2192c7ce..9b67ec39f 100644 --- a/src/WebApi_dtu.cpp +++ b/src/WebApi_dtu.cpp @@ -73,8 +73,7 @@ void WebApiDtuClass::onDtuAdminGet(AsyncWebServerRequest* request) obj["freq_legal_max"] = definition.definition.Freq_Legal_Max; } - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request) @@ -99,8 +98,7 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request) && root.containsKey("cmt_country"))) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -110,40 +108,35 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request) if (serial == 0) { retMsg["message"] = "Serial cannot be zero!"; retMsg["code"] = WebApiError::DtuSerialZero; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } if (root["pollinterval"].as() == 0) { retMsg["message"] = "Poll interval must be greater zero!"; retMsg["code"] = WebApiError::DtuPollZero; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } if (root["nrf_palevel"].as() > 3) { retMsg["message"] = "Invalid power level setting!"; retMsg["code"] = WebApiError::DtuInvalidPowerLevel; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } if (root["cmt_palevel"].as() < -10 || root["cmt_palevel"].as() > 20) { retMsg["message"] = "Invalid power level setting!"; retMsg["code"] = WebApiError::DtuInvalidPowerLevel; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } if (root["cmt_country"].as() >= CountryModeId_t::CountryModeId_Max) { retMsg["message"] = "Invalid country setting!"; retMsg["code"] = WebApiError::DtuInvalidCmtCountry; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -156,8 +149,7 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request) retMsg["code"] = WebApiError::DtuInvalidCmtFrequency; retMsg["param"]["min"] = FrequencyDefinition.Freq_Min; retMsg["param"]["max"] = FrequencyDefinition.Freq_Max; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -172,8 +164,7 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request) WebApi.writeConfig(retMsg); - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); _applyDataTask.enable(); _applyDataTask.restart(); diff --git a/src/WebApi_eventlog.cpp b/src/WebApi_eventlog.cpp index 3637a3d9e..e2d34442f 100644 --- a/src/WebApi_eventlog.cpp +++ b/src/WebApi_eventlog.cpp @@ -62,6 +62,5 @@ void WebApiEventlogClass::onEventlogStatus(AsyncWebServerRequest* request) } } - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } diff --git a/src/WebApi_gridprofile.cpp b/src/WebApi_gridprofile.cpp index 2527396d5..5ed579d04 100644 --- a/src/WebApi_gridprofile.cpp +++ b/src/WebApi_gridprofile.cpp @@ -55,8 +55,7 @@ void WebApiGridProfileClass::onGridProfileStatus(AsyncWebServerRequest* request) } } - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } void WebApiGridProfileClass::onGridProfileRawdata(AsyncWebServerRequest* request) @@ -83,6 +82,5 @@ void WebApiGridProfileClass::onGridProfileRawdata(AsyncWebServerRequest* request copyArray(&data[0], data.size(), raw); } - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } diff --git a/src/WebApi_inverter.cpp b/src/WebApi_inverter.cpp index 0d82a3264..2d9a56344 100644 --- a/src/WebApi_inverter.cpp +++ b/src/WebApi_inverter.cpp @@ -77,8 +77,7 @@ void WebApiInverterClass::onInverterList(AsyncWebServerRequest* request) } } - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } void WebApiInverterClass::onInverterAdd(AsyncWebServerRequest* request) @@ -99,8 +98,7 @@ void WebApiInverterClass::onInverterAdd(AsyncWebServerRequest* request) && root.containsKey("name"))) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -110,8 +108,7 @@ void WebApiInverterClass::onInverterAdd(AsyncWebServerRequest* request) if (serial == 0) { retMsg["message"] = "Serial must be a number > 0!"; retMsg["code"] = WebApiError::InverterSerialZero; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -119,8 +116,7 @@ void WebApiInverterClass::onInverterAdd(AsyncWebServerRequest* request) retMsg["message"] = "Name must between 1 and " STR(INV_MAX_NAME_STRLEN) " characters long!"; retMsg["code"] = WebApiError::InverterNameLength; retMsg["param"]["max"] = INV_MAX_NAME_STRLEN; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -130,8 +126,7 @@ void WebApiInverterClass::onInverterAdd(AsyncWebServerRequest* request) retMsg["message"] = "Only " STR(INV_MAX_COUNT) " inverters are supported!"; retMsg["code"] = WebApiError::InverterCount; retMsg["param"]["max"] = INV_MAX_COUNT; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -142,8 +137,7 @@ void WebApiInverterClass::onInverterAdd(AsyncWebServerRequest* request) WebApi.writeConfig(retMsg, WebApiError::InverterAdded, "Inverter created!"); - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); auto inv = Hoymiles.addInverter(inverter->Name, inverter->Serial); @@ -173,16 +167,14 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request) if (!(root.containsKey("id") && root.containsKey("serial") && root.containsKey("name") && root.containsKey("channel"))) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } if (root["id"].as() > INV_MAX_COUNT - 1) { retMsg["message"] = "Invalid ID specified!"; retMsg["code"] = WebApiError::InverterInvalidId; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -192,8 +184,7 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request) if (serial == 0) { retMsg["message"] = "Serial must be a number > 0!"; retMsg["code"] = WebApiError::InverterSerialZero; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -201,8 +192,7 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request) retMsg["message"] = "Name must between 1 and " STR(INV_MAX_NAME_STRLEN) " characters long!"; retMsg["code"] = WebApiError::InverterNameLength; retMsg["param"]["max"] = INV_MAX_NAME_STRLEN; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -210,8 +200,7 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request) if (channelArray.size() == 0 || channelArray.size() > INV_MAX_CHAN_COUNT) { retMsg["message"] = "Invalid amount of max channel setting given!"; retMsg["code"] = WebApiError::InverterInvalidMaxChannel; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -243,8 +232,7 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request) WebApi.writeConfig(retMsg, WebApiError::InverterChanged, "Inverter changed!"); - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); std::shared_ptr inv = Hoymiles.getInverterBySerial(old_serial); @@ -293,16 +281,14 @@ void WebApiInverterClass::onInverterDelete(AsyncWebServerRequest* request) if (!(root.containsKey("id"))) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } if (root["id"].as() > INV_MAX_COUNT - 1) { retMsg["message"] = "Invalid ID specified!"; retMsg["code"] = WebApiError::InverterInvalidId; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -315,8 +301,7 @@ void WebApiInverterClass::onInverterDelete(AsyncWebServerRequest* request) WebApi.writeConfig(retMsg, WebApiError::InverterDeleted, "Inverter deleted!"); - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); MqttHandleHass.forceUpdate(); } @@ -338,8 +323,7 @@ void WebApiInverterClass::onInverterOrder(AsyncWebServerRequest* request) if (!(root.containsKey("order"))) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -357,6 +341,5 @@ void WebApiInverterClass::onInverterOrder(AsyncWebServerRequest* request) WebApi.writeConfig(retMsg, WebApiError::InverterOrdered, "Inverter order saved!"); - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } diff --git a/src/WebApi_limit.cpp b/src/WebApi_limit.cpp index 79d6039fc..9a622deae 100644 --- a/src/WebApi_limit.cpp +++ b/src/WebApi_limit.cpp @@ -47,8 +47,7 @@ void WebApiLimitClass::onLimitStatus(AsyncWebServerRequest* request) root[serial]["limit_set_status"] = limitStatus; } - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } void WebApiLimitClass::onLimitPost(AsyncWebServerRequest* request) @@ -70,8 +69,7 @@ void WebApiLimitClass::onLimitPost(AsyncWebServerRequest* request) && root.containsKey("limit_type"))) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -81,8 +79,7 @@ void WebApiLimitClass::onLimitPost(AsyncWebServerRequest* request) if (serial == 0) { retMsg["message"] = "Serial must be a number > 0!"; retMsg["code"] = WebApiError::LimitSerialZero; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -90,8 +87,7 @@ void WebApiLimitClass::onLimitPost(AsyncWebServerRequest* request) retMsg["message"] = "Limit must between 0 and " STR(MAX_INVERTER_LIMIT) "!"; retMsg["code"] = WebApiError::LimitInvalidLimit; retMsg["param"]["max"] = MAX_INVERTER_LIMIT; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -102,8 +98,7 @@ void WebApiLimitClass::onLimitPost(AsyncWebServerRequest* request) retMsg["message"] = "Invalid type specified!"; retMsg["code"] = WebApiError::LimitInvalidType; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -114,8 +109,7 @@ void WebApiLimitClass::onLimitPost(AsyncWebServerRequest* request) if (inv == nullptr) { retMsg["message"] = "Invalid inverter specified!"; retMsg["code"] = WebApiError::LimitInvalidInverter; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -125,6 +119,5 @@ void WebApiLimitClass::onLimitPost(AsyncWebServerRequest* request) retMsg["message"] = "Settings saved!"; retMsg["code"] = WebApiError::GenericSuccess; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } diff --git a/src/WebApi_maintenance.cpp b/src/WebApi_maintenance.cpp index a7eeb4240..1504f9d75 100644 --- a/src/WebApi_maintenance.cpp +++ b/src/WebApi_maintenance.cpp @@ -33,8 +33,7 @@ void WebApiMaintenanceClass::onRebootPost(AsyncWebServerRequest* request) if (!(root.containsKey("reboot"))) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -43,14 +42,12 @@ void WebApiMaintenanceClass::onRebootPost(AsyncWebServerRequest* request) retMsg["message"] = "Reboot triggered!"; retMsg["code"] = WebApiError::MaintenanceRebootTriggered; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); Utils::restartDtu(); } else { retMsg["message"] = "Reboot cancled!"; retMsg["code"] = WebApiError::MaintenanceRebootCancled; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } } diff --git a/src/WebApi_mqtt.cpp b/src/WebApi_mqtt.cpp index 88c2a4ab2..1795b7aae 100644 --- a/src/WebApi_mqtt.cpp +++ b/src/WebApi_mqtt.cpp @@ -50,8 +50,7 @@ void WebApiMqttClass::onMqttStatus(AsyncWebServerRequest* request) root["mqtt_hass_topic"] = config.Mqtt.Hass.Topic; root["mqtt_hass_individualpanels"] = config.Mqtt.Hass.IndividualPanels; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } void WebApiMqttClass::onMqttAdminGet(AsyncWebServerRequest* request) @@ -88,8 +87,7 @@ void WebApiMqttClass::onMqttAdminGet(AsyncWebServerRequest* request) root["mqtt_hass_topic"] = config.Mqtt.Hass.Topic; root["mqtt_hass_individualpanels"] = config.Mqtt.Hass.IndividualPanels; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request) @@ -130,8 +128,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request) && root.containsKey("mqtt_hass_individualpanels"))) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -140,8 +137,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request) retMsg["message"] = "MqTT Server must between 1 and " STR(MQTT_MAX_HOSTNAME_STRLEN) " characters long!"; retMsg["code"] = WebApiError::MqttHostnameLength; retMsg["param"]["max"] = MQTT_MAX_HOSTNAME_STRLEN; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -149,48 +145,42 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request) retMsg["message"] = "Username must not be longer than " STR(MQTT_MAX_USERNAME_STRLEN) " characters!"; retMsg["code"] = WebApiError::MqttUsernameLength; retMsg["param"]["max"] = MQTT_MAX_USERNAME_STRLEN; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } if (root["mqtt_password"].as().length() > MQTT_MAX_PASSWORD_STRLEN) { retMsg["message"] = "Password must not be longer than " STR(MQTT_MAX_PASSWORD_STRLEN) " characters!"; retMsg["code"] = WebApiError::MqttPasswordLength; retMsg["param"]["max"] = MQTT_MAX_PASSWORD_STRLEN; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } if (root["mqtt_topic"].as().length() > MQTT_MAX_TOPIC_STRLEN) { retMsg["message"] = "Topic must not be longer than " STR(MQTT_MAX_TOPIC_STRLEN) " characters!"; retMsg["code"] = WebApiError::MqttTopicLength; retMsg["param"]["max"] = MQTT_MAX_TOPIC_STRLEN; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } if (root["mqtt_topic"].as().indexOf(' ') != -1) { retMsg["message"] = "Topic must not contain space characters!"; retMsg["code"] = WebApiError::MqttTopicCharacter; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } if (!root["mqtt_topic"].as().endsWith("/")) { retMsg["message"] = "Topic must end with a slash (/)!"; retMsg["code"] = WebApiError::MqttTopicTrailingSlash; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } if (root["mqtt_port"].as() == 0 || root["mqtt_port"].as() > 65535) { retMsg["message"] = "Port must be a number between 1 and 65535!"; retMsg["code"] = WebApiError::MqttPort; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -200,8 +190,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request) retMsg["message"] = "Certificates must not be longer than " STR(MQTT_MAX_CERT_STRLEN) " characters!"; retMsg["code"] = WebApiError::MqttCertificateLength; retMsg["param"]["max"] = MQTT_MAX_CERT_STRLEN; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -209,16 +198,14 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request) retMsg["message"] = "LWT topic must not be longer than " STR(MQTT_MAX_TOPIC_STRLEN) " characters!"; retMsg["code"] = WebApiError::MqttLwtTopicLength; retMsg["param"]["max"] = MQTT_MAX_TOPIC_STRLEN; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } if (root["mqtt_lwt_topic"].as().indexOf(' ') != -1) { retMsg["message"] = "LWT topic must not contain space characters!"; retMsg["code"] = WebApiError::MqttLwtTopicCharacter; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -226,8 +213,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request) retMsg["message"] = "LWT online value must not be longer than " STR(MQTT_MAX_LWTVALUE_STRLEN) " characters!"; retMsg["code"] = WebApiError::MqttLwtOnlineLength; retMsg["param"]["max"] = MQTT_MAX_LWTVALUE_STRLEN; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -235,8 +221,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request) retMsg["message"] = "LWT offline value must not be longer than " STR(MQTT_MAX_LWTVALUE_STRLEN) " characters!"; retMsg["code"] = WebApiError::MqttLwtOfflineLength; retMsg["param"]["max"] = MQTT_MAX_LWTVALUE_STRLEN; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -244,8 +229,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request) retMsg["message"] = "LWT QoS must not be greater than " STR(2) "!"; retMsg["code"] = WebApiError::MqttLwtQos; retMsg["param"]["max"] = 2; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -254,8 +238,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request) retMsg["code"] = WebApiError::MqttPublishInterval; retMsg["param"]["min"] = 5; retMsg["param"]["max"] = 65535; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -264,16 +247,14 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request) retMsg["message"] = "Hass topic must not be longer than " STR(MQTT_MAX_TOPIC_STRLEN) " characters!"; retMsg["code"] = WebApiError::MqttHassTopicLength; retMsg["param"]["max"] = MQTT_MAX_TOPIC_STRLEN; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } if (root["mqtt_hass_topic"].as().indexOf(' ') != -1) { retMsg["message"] = "Hass topic must not contain space characters!"; retMsg["code"] = WebApiError::MqttHassTopicCharacter; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } } @@ -306,8 +287,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request) WebApi.writeConfig(retMsg); - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); MqttSettings.performReconnect(); MqttHandleHass.forceUpdate(); diff --git a/src/WebApi_network.cpp b/src/WebApi_network.cpp index 158c8bde9..7fec44b2a 100644 --- a/src/WebApi_network.cpp +++ b/src/WebApi_network.cpp @@ -46,8 +46,7 @@ void WebApiNetworkClass::onNetworkStatus(AsyncWebServerRequest* request) root["ap_mac"] = WiFi.softAPmacAddress(); root["ap_stationnum"] = WiFi.softAPgetStationNum(); - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } void WebApiNetworkClass::onNetworkAdminGet(AsyncWebServerRequest* request) @@ -72,8 +71,7 @@ void WebApiNetworkClass::onNetworkAdminGet(AsyncWebServerRequest* request) root["aptimeout"] = config.WiFi.ApTimeout; root["mdnsenabled"] = config.Mdns.Enabled; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } void WebApiNetworkClass::onNetworkAdminPost(AsyncWebServerRequest* request) @@ -102,8 +100,7 @@ void WebApiNetworkClass::onNetworkAdminPost(AsyncWebServerRequest* request) && root.containsKey("aptimeout"))) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -111,68 +108,59 @@ void WebApiNetworkClass::onNetworkAdminPost(AsyncWebServerRequest* request) if (!ipaddress.fromString(root["ipaddress"].as())) { retMsg["message"] = "IP address is invalid!"; retMsg["code"] = WebApiError::NetworkIpInvalid; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } IPAddress netmask; if (!netmask.fromString(root["netmask"].as())) { retMsg["message"] = "Netmask is invalid!"; retMsg["code"] = WebApiError::NetworkNetmaskInvalid; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } IPAddress gateway; if (!gateway.fromString(root["gateway"].as())) { retMsg["message"] = "Gateway is invalid!"; retMsg["code"] = WebApiError::NetworkGatewayInvalid; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } IPAddress dns1; if (!dns1.fromString(root["dns1"].as())) { retMsg["message"] = "DNS Server IP 1 is invalid!"; retMsg["code"] = WebApiError::NetworkDns1Invalid; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } IPAddress dns2; if (!dns2.fromString(root["dns2"].as())) { retMsg["message"] = "DNS Server IP 2 is invalid!"; retMsg["code"] = WebApiError::NetworkDns2Invalid; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } if (root["hostname"].as().length() == 0 || root["hostname"].as().length() > WIFI_MAX_HOSTNAME_STRLEN) { retMsg["message"] = "Hostname must between 1 and " STR(WIFI_MAX_HOSTNAME_STRLEN) " characters long!"; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } if (NetworkSettings.NetworkMode() == network_mode::WiFi) { if (root["ssid"].as().length() == 0 || root["ssid"].as().length() > WIFI_MAX_SSID_STRLEN) { retMsg["message"] = "SSID must between 1 and " STR(WIFI_MAX_SSID_STRLEN) " characters long!"; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } } if (root["password"].as().length() > WIFI_MAX_PASSWORD_STRLEN - 1) { retMsg["message"] = "Password must not be longer than " STR(WIFI_MAX_PASSWORD_STRLEN) " characters long!"; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } if (root["aptimeout"].as() > 99999) { retMsg["message"] = "ApTimeout must be a number between 0 and 99999!"; retMsg["code"] = WebApiError::NetworkApTimeoutInvalid; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -210,8 +198,7 @@ void WebApiNetworkClass::onNetworkAdminPost(AsyncWebServerRequest* request) WebApi.writeConfig(retMsg); - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); NetworkSettings.enableAdminMode(); NetworkSettings.applyConfig(); diff --git a/src/WebApi_ntp.cpp b/src/WebApi_ntp.cpp index 07553921d..d50e0f02f 100644 --- a/src/WebApi_ntp.cpp +++ b/src/WebApi_ntp.cpp @@ -63,8 +63,7 @@ void WebApiNtpClass::onNtpStatus(AsyncWebServerRequest* request) root["sun_isSunsetAvailable"] = SunPosition.isSunsetAvailable(); root["sun_isDayPeriod"] = SunPosition.isDayPeriod(); - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } void WebApiNtpClass::onNtpAdminGet(AsyncWebServerRequest* request) @@ -84,8 +83,7 @@ void WebApiNtpClass::onNtpAdminGet(AsyncWebServerRequest* request) root["latitude"] = config.Ntp.Latitude; root["sunsettype"] = config.Ntp.SunsetType; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } void WebApiNtpClass::onNtpAdminPost(AsyncWebServerRequest* request) @@ -109,8 +107,7 @@ void WebApiNtpClass::onNtpAdminPost(AsyncWebServerRequest* request) && root.containsKey("sunsettype"))) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -118,8 +115,7 @@ void WebApiNtpClass::onNtpAdminPost(AsyncWebServerRequest* request) retMsg["message"] = "NTP Server must between 1 and " STR(NTP_MAX_SERVER_STRLEN) " characters long!"; retMsg["code"] = WebApiError::NtpServerLength; retMsg["param"]["max"] = NTP_MAX_SERVER_STRLEN; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -127,8 +123,7 @@ void WebApiNtpClass::onNtpAdminPost(AsyncWebServerRequest* request) retMsg["message"] = "Timezone must between 1 and " STR(NTP_MAX_TIMEZONE_STRLEN) " characters long!"; retMsg["code"] = WebApiError::NtpTimezoneLength; retMsg["param"]["max"] = NTP_MAX_TIMEZONE_STRLEN; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -136,8 +131,7 @@ void WebApiNtpClass::onNtpAdminPost(AsyncWebServerRequest* request) retMsg["message"] = "Timezone description must between 1 and " STR(NTP_MAX_TIMEZONEDESCR_STRLEN) " characters long!"; retMsg["code"] = WebApiError::NtpTimezoneDescriptionLength; retMsg["param"]["max"] = NTP_MAX_TIMEZONEDESCR_STRLEN; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -151,8 +145,7 @@ void WebApiNtpClass::onNtpAdminPost(AsyncWebServerRequest* request) WebApi.writeConfig(retMsg); - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); NtpSettings.setServer(); NtpSettings.setTimezone(); @@ -183,8 +176,7 @@ void WebApiNtpClass::onNtpTimeGet(AsyncWebServerRequest* request) root["minute"] = timeinfo.tm_min; root["second"] = timeinfo.tm_sec; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } void WebApiNtpClass::onNtpTimePost(AsyncWebServerRequest* request) @@ -209,8 +201,7 @@ void WebApiNtpClass::onNtpTimePost(AsyncWebServerRequest* request) && root.containsKey("second"))) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -219,8 +210,7 @@ void WebApiNtpClass::onNtpTimePost(AsyncWebServerRequest* request) retMsg["code"] = WebApiError::NtpYearInvalid; retMsg["param"]["min"] = 2022; retMsg["param"]["max"] = 2100; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -229,8 +219,7 @@ void WebApiNtpClass::onNtpTimePost(AsyncWebServerRequest* request) retMsg["code"] = WebApiError::NtpMonthInvalid; retMsg["param"]["min"] = 1; retMsg["param"]["max"] = 12; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -239,8 +228,7 @@ void WebApiNtpClass::onNtpTimePost(AsyncWebServerRequest* request) retMsg["code"] = WebApiError::NtpDayInvalid; retMsg["param"]["min"] = 1; retMsg["param"]["max"] = 31; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -249,8 +237,7 @@ void WebApiNtpClass::onNtpTimePost(AsyncWebServerRequest* request) retMsg["code"] = WebApiError::NtpHourInvalid; retMsg["param"]["min"] = 0; retMsg["param"]["max"] = 23; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -259,8 +246,7 @@ void WebApiNtpClass::onNtpTimePost(AsyncWebServerRequest* request) retMsg["code"] = WebApiError::NtpMinuteInvalid; retMsg["param"]["min"] = 0; retMsg["param"]["max"] = 59; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -269,8 +255,7 @@ void WebApiNtpClass::onNtpTimePost(AsyncWebServerRequest* request) retMsg["code"] = WebApiError::NtpSecondInvalid; retMsg["param"]["min"] = 0; retMsg["param"]["max"] = 59; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -291,6 +276,5 @@ void WebApiNtpClass::onNtpTimePost(AsyncWebServerRequest* request) retMsg["message"] = "Time updated!"; retMsg["code"] = WebApiError::NtpTimeUpdated; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } diff --git a/src/WebApi_power.cpp b/src/WebApi_power.cpp index f019ce334..b2b2ce42e 100644 --- a/src/WebApi_power.cpp +++ b/src/WebApi_power.cpp @@ -40,8 +40,7 @@ void WebApiPowerClass::onPowerStatus(AsyncWebServerRequest* request) root[inv->serialString()]["power_set_status"] = limitStatus; } - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } void WebApiPowerClass::onPowerPost(AsyncWebServerRequest* request) @@ -63,8 +62,7 @@ void WebApiPowerClass::onPowerPost(AsyncWebServerRequest* request) || root.containsKey("restart")))) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -74,8 +72,7 @@ void WebApiPowerClass::onPowerPost(AsyncWebServerRequest* request) if (serial == 0) { retMsg["message"] = "Serial must be a number > 0!"; retMsg["code"] = WebApiError::PowerSerialZero; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -83,8 +80,7 @@ void WebApiPowerClass::onPowerPost(AsyncWebServerRequest* request) if (inv == nullptr) { retMsg["message"] = "Invalid inverter specified!"; retMsg["code"] = WebApiError::PowerInvalidInverter; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -101,6 +97,5 @@ void WebApiPowerClass::onPowerPost(AsyncWebServerRequest* request) retMsg["message"] = "Settings saved!"; retMsg["code"] = WebApiError::GenericSuccess; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } diff --git a/src/WebApi_security.cpp b/src/WebApi_security.cpp index 78eaffe0b..eb0f27d20 100644 --- a/src/WebApi_security.cpp +++ b/src/WebApi_security.cpp @@ -31,8 +31,7 @@ void WebApiSecurityClass::onSecurityGet(AsyncWebServerRequest* request) root["password"] = config.Security.Password; root["allow_readonly"] = config.Security.AllowReadonly; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } void WebApiSecurityClass::onSecurityPost(AsyncWebServerRequest* request) @@ -53,8 +52,7 @@ void WebApiSecurityClass::onSecurityPost(AsyncWebServerRequest* request) && root.containsKey("allow_readonly")) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -62,8 +60,7 @@ void WebApiSecurityClass::onSecurityPost(AsyncWebServerRequest* request) retMsg["message"] = "Password must between 8 and " STR(WIFI_MAX_PASSWORD_STRLEN) " characters long!"; retMsg["code"] = WebApiError::SecurityPasswordLength; retMsg["param"]["max"] = WIFI_MAX_PASSWORD_STRLEN; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); return; } @@ -73,8 +70,7 @@ void WebApiSecurityClass::onSecurityPost(AsyncWebServerRequest* request) WebApi.writeConfig(retMsg); - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } void WebApiSecurityClass::onAuthenticateGet(AsyncWebServerRequest* request) @@ -89,6 +85,5 @@ void WebApiSecurityClass::onAuthenticateGet(AsyncWebServerRequest* request) retMsg["message"] = "Authentication successful!"; retMsg["code"] = WebApiError::SecurityAuthSuccess; - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } diff --git a/src/WebApi_sysstatus.cpp b/src/WebApi_sysstatus.cpp index 11bd29c20..a2893c820 100644 --- a/src/WebApi_sysstatus.cpp +++ b/src/WebApi_sysstatus.cpp @@ -76,6 +76,5 @@ void WebApiSysstatusClass::onSystemStatus(AsyncWebServerRequest* request) root["cmt_configured"] = PinMapping.isValidCmt2300Config(); root["cmt_connected"] = Hoymiles.getRadioCmt()->isConnected(); - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } diff --git a/src/WebApi_ws_live.cpp b/src/WebApi_ws_live.cpp index f378e3ab1..e79c664ab 100644 --- a/src/WebApi_ws_live.cpp +++ b/src/WebApi_ws_live.cpp @@ -255,12 +255,7 @@ void WebApiWsLiveClass::onLivedataStatus(AsyncWebServerRequest* request) generateCommonJsonResponse(root); - if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) { - return; - } - - response->setLength(); - request->send(response); + WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__); } catch (const std::bad_alloc& bad_alloc) { MessageOutput.printf("Call to /api/livedata/status temporarely out of resources. Reason: \"%s\".\r\n", bad_alloc.what()); diff --git a/webapp/src/locales/de.json b/webapp/src/locales/de.json index c9dfa975b..ad184d1ce 100644 --- a/webapp/src/locales/de.json +++ b/webapp/src/locales/de.json @@ -32,6 +32,9 @@ "Release": "Loslassen zum Aktualisieren", "Close": "Schließen" }, + "Error": { + "Oops": "Oops!" + }, "localeswitcher": { "Dark": "Dunkel", "Light": "Hell", diff --git a/webapp/src/locales/en.json b/webapp/src/locales/en.json index 4375137b9..4179227ae 100644 --- a/webapp/src/locales/en.json +++ b/webapp/src/locales/en.json @@ -32,6 +32,9 @@ "Release": "Release to refresh", "Close": "Close" }, + "Error": { + "Oops": "Oops!" + }, "localeswitcher": { "Dark": "Dark", "Light": "Light", diff --git a/webapp/src/locales/fr.json b/webapp/src/locales/fr.json index 24f0a951d..c60a552af 100644 --- a/webapp/src/locales/fr.json +++ b/webapp/src/locales/fr.json @@ -32,6 +32,9 @@ "Release": "Release to refresh", "Close": "Fermer" }, + "Error": { + "Oops": "Oops!" + }, "localeswitcher": { "Dark": "Sombre", "Light": "Clair", diff --git a/webapp/src/router/index.ts b/webapp/src/router/index.ts index 6cfc00ef8..8fd3cfe83 100644 --- a/webapp/src/router/index.ts +++ b/webapp/src/router/index.ts @@ -3,6 +3,7 @@ import ConfigAdminView from '@/views/ConfigAdminView.vue'; import ConsoleInfoView from '@/views/ConsoleInfoView.vue'; import DeviceAdminView from '@/views/DeviceAdminView.vue' import DtuAdminView from '@/views/DtuAdminView.vue'; +import ErrorView from '@/views/ErrorView.vue'; import FirmwareUpgradeView from '@/views/FirmwareUpgradeView.vue'; import HomeView from '@/views/HomeView.vue'; import InverterAdminView from '@/views/InverterAdminView.vue'; @@ -32,6 +33,11 @@ const router = createRouter({ name: 'Login', component: LoginView }, + { + path: '/error?status=:status&message=:message', + name: 'Error', + component: ErrorView + }, { path: '/about', name: 'About', @@ -115,4 +121,4 @@ const router = createRouter({ ] }); -export default router; \ No newline at end of file +export default router; diff --git a/webapp/src/utils/authentication.ts b/webapp/src/utils/authentication.ts index d1f87e3d8..52d92fd98 100644 --- a/webapp/src/utils/authentication.ts +++ b/webapp/src/utils/authentication.ts @@ -77,6 +77,7 @@ export function handleResponse(response: Response, emitter: Emitter + + + + + + diff --git a/webapp/src/views/FirmwareUpgradeView.vue b/webapp/src/views/FirmwareUpgradeView.vue index 738460791..f7bf0d75f 100644 --- a/webapp/src/views/FirmwareUpgradeView.vue +++ b/webapp/src/views/FirmwareUpgradeView.vue @@ -191,7 +191,7 @@ export default defineComponent({ const remoteHostUrl = "/api/system/status"; // Use a simple fetch request to check if the remote host is reachable - fetch(remoteHostUrl, { method: 'HEAD' }) + fetch(remoteHostUrl, { method: 'GET' }) .then(response => { // Check if the response status is OK (200-299 range) if (response.ok) {