JSON HTTP error handling

This commit is contained in:
Blaz Kristan 2023-12-12 15:45:57 +01:00
parent f69edefddf
commit 67ae716c60
4 changed files with 20 additions and 7 deletions

View File

@ -342,8 +342,9 @@
// WLED Error modes // WLED Error modes
#define ERR_NONE 0 // All good :) #define ERR_NONE 0 // All good :)
#define ERR_DENIED 1 // Permission denied #define ERR_DENIED 1 // Permission denied
#define ERR_EEP_COMMIT 2 // Could not commit to EEPROM (wrong flash layout?) OBSOLETE #define ERR_CONCURRENCY 2 // Conurrency (client active)
#define ERR_NOBUF 3 // JSON buffer was not released in time, request cannot be handled at this time #define ERR_NOBUF 3 // JSON buffer was not released in time, request cannot be handled at this time
#define ERR_NOT_IMPL 4 // Not implemented
#define ERR_JSON 9 // JSON parsing failed (input too large?) #define ERR_JSON 9 // JSON parsing failed (input too large?)
#define ERR_FS_BEGIN 10 // Could not init filesystem (no partition?) #define ERR_FS_BEGIN 10 // Could not init filesystem (no partition?)
#define ERR_FS_QUOTA 11 // The FS is full or the maximum file size is reached #define ERR_FS_QUOTA 11 // The FS is full or the maximum file size is reached

View File

@ -399,10 +399,10 @@ bool isIp(String str);
void createEditHandler(bool enable); void createEditHandler(bool enable);
bool captivePortal(AsyncWebServerRequest *request); bool captivePortal(AsyncWebServerRequest *request);
void initServer(); void initServer();
void serveIndexOrWelcome(AsyncWebServerRequest *request);
void serveIndex(AsyncWebServerRequest* request); void serveIndex(AsyncWebServerRequest* request);
String msgProcessor(const String& var); String msgProcessor(const String& var);
void serveMessage(AsyncWebServerRequest* request, uint16_t code, const String& headl, const String& subl="", byte optionT=255); void serveMessage(AsyncWebServerRequest* request, uint16_t code, const String& headl, const String& subl="", byte optionT=255);
void serveJsonError(AsyncWebServerRequest* request, uint16_t code, uint16_t error);
String dmxProcessor(const String& var); String dmxProcessor(const String& var);
void serveSettings(AsyncWebServerRequest* request, bool post = false); void serveSettings(AsyncWebServerRequest* request, bool post = false);
void serveSettingsJS(AsyncWebServerRequest* request); void serveSettingsJS(AsyncWebServerRequest* request);

View File

@ -1012,7 +1012,7 @@ static volatile bool servingClient = false;
void serveJson(AsyncWebServerRequest* request) void serveJson(AsyncWebServerRequest* request)
{ {
if (servingClient) { if (servingClient) {
request->send(503, "application/json", F("{\"error\":2}")); // ERR_CONCURENCY serveJsonError(request, 503, ERR_CONCURRENCY);
return; return;
} }
servingClient = true; servingClient = true;
@ -1044,13 +1044,13 @@ void serveJson(AsyncWebServerRequest* request)
return; return;
} }
else if (url.length() > 6) { //not just /json else if (url.length() > 6) { //not just /json
request->send(501, "application/json", F("{\"error\":\"Not implemented\"}")); serveJsonError(request, 501, ERR_NOT_IMPL);
servingClient = false; servingClient = false;
return; return;
} }
if (!requestJSONBufferLock(17)) { if (!requestJSONBufferLock(17)) {
request->send(503, "application/json", F("{\"error\":3}")); serveJsonError(request, 503, ERR_NOBUF);
servingClient = false; servingClient = false;
return; return;
} }

View File

@ -183,7 +183,7 @@ void initServer()
JsonObject root = doc.as<JsonObject>(); JsonObject root = doc.as<JsonObject>();
if (error || root.isNull()) { if (error || root.isNull()) {
releaseJSONBufferLock(); releaseJSONBufferLock();
request->send(400, "application/json", F("{\"error\":9}")); // ERR_JSON serveJsonError(request, 400, ERR_JSON);
return; return;
} }
if (root.containsKey("pin")) checkSettingsPIN(root["pin"].as<const char*>()); if (root.containsKey("pin")) checkSettingsPIN(root["pin"].as<const char*>());
@ -201,8 +201,8 @@ void initServer()
verboseResponse = deserializeState(root); verboseResponse = deserializeState(root);
} else { } else {
if (!correctPIN && strlen(settingsPIN)>0) { if (!correctPIN && strlen(settingsPIN)>0) {
request->send(401, "application/json", F("{\"error\":1}")); // ERR_DENIED
releaseJSONBufferLock(); releaseJSONBufferLock();
serveJsonError(request, 401, ERR_DENIED);
return; return;
} }
verboseResponse = deserializeConfig(root); //use verboseResponse to determine whether cfg change should be saved immediately verboseResponse = deserializeConfig(root); //use verboseResponse to determine whether cfg change should be saved immediately
@ -509,6 +509,18 @@ void serveMessage(AsyncWebServerRequest* request, uint16_t code, const String& h
} }
void serveJsonError(AsyncWebServerRequest* request, uint16_t code, uint16_t error)
{
AsyncJsonResponse *response = new AsyncJsonResponse(64);
if (error < ERR_NOT_IMPL) response->addHeader("Retry-After", "1");
response->setContentType("application/json");
response->setCode(code);
JsonObject obj = response->getRoot();
obj[F("error")] = error;
response->setLength();
request->send(response);
}
#ifdef WLED_ENABLE_DMX #ifdef WLED_ENABLE_DMX
String dmxProcessor(const String& var) String dmxProcessor(const String& var)
{ {