In this ESP32 tutorial, we will check how to define a custom handling function to be executed when a route is not found on a HTTP web server running on the ESP32. The tests of this ESP32 tutorial were performed using a DFRobot’s ESP-WROOM-32 device integrated in a ESP32 development board.
Introduction
In this ESP32 tutorial, we will check how to define a custom handling function to be executed when a route is not found on a HTTP web server running on the ESP32.
You can check an introductory tutorial on the async HTTP web server libraries for the ESP32 here. For more tutorials on the HTTP server, please check the Related Posts section at the end of this article.
The tests shown here were performed using a DFRobot’s ESP-WROOM-32 device integrated in a ESP32 FireBeetle board.
The code
We will start the code by including all the necessary libraries to connect the ESP to a WiFi network and to setup the server.
Followed by that, we will declare the credentials of the WiFi network in two global variables. To finish the global variables declaration, we need an object of class AsyncWebServer, which will be used to configure the server.
#include <WiFi.h>
#include <FS.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";
AsyncWebServer server(80);
Moving on to the setup function, we will first open a serial connection to be able to output some information from our program.
Next we will connect the device to the WiFi network, using the same procedure we have been using in the previous tutorials. Please check here if you need a more complete explanation on how to connect the ESP32 to a wireless network.
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
Now we need to take care of setting up the server. In our case, we only want to configure the handling function for when a client request doesn’t match any routes. Thus, we won’t declare any route, which means that any request made to the server should be treated by the not found function.
So, in order to bind the handling function with the not found event, we simply need to call the onNotFound method on the server object and pass as input the handling function that will be executed when requests are made to the server and no route is matched.
Note that this handling function that we pass as input of the onNotFound method has a fixed prototype, the same way the handling functions we bind to routes have. This prototype is defined by the ArRequestHandlerFunction type, which can be analysed in this header file.
Thus, the handling function needs to return null and receive as input a pointer to an object of class AsyncWebServerRequest.
If we compare it against the code we have been developing in previous tutorials about the async HTTP server, this is the same prototype of handling functions that the on method receives when we are declaring routes.
In order to keep things compact, we will declare the function as a C++ lambda.
server.onNotFound([](AsyncWebServerRequest *request){
// Handling function code
});
In the handling function, we can use the request object pointer to return an answer to the client. To do it, we simply, use the send method that we use in any regular route.
This method receives as first input the HTTP response code, as second the content-type and as third the actual content.
Since this is a route not found handling function, we will return to the client a 404 HTTP response code. As content, we will return a plain text string with a message indicating that the content was not found.
server.onNotFound([](AsyncWebServerRequest *request){
request->send(404, "text/plain", "The content you are looking for was not found.");
});
To finalize we call the begin method on the server object, to start it. After that, the server should be listening to incoming HTTP requests. The complete final code can be seen below.
#include <WiFi.h>
#include <FS.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";
AsyncWebServer server(80);
void setup(){
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
server.onNotFound([](AsyncWebServerRequest *request){
request->send(404, "text/plain", "The content you are looking for was not found.");
});
server.begin();
}
void loop(){}
Testing the code
To test the code, you we just need to compile it and upload it to the ESP32. After that, we need to open the IDE serial monitor and copy the IP that gets printed once the connection to the wireless network is established.
After that, we simply need to open a web browser and paste the following URL on the address bar, changing {EspIp} by the IP copied and {route} by a route of our choice (it doesn’t matter the route used since all will be caught by the not found handler).
You should get an output similar to figure 1, which shows the custom message we defined for the not found being returned.
Figure 1 – Output of the not found handling function.