MQTT Error Reporting
Unlike HTTP, the MQTT protocol does not provide a standard way of reporting errors to connected clients. This poses a problem for Adafruit IO, because there are multiple reasons why sending data to Adafruit IO might fail.
Here are a few common examples:
- Publishing data to an invalid topic
- Publishing data to an unauthorized topic
- Publishing data too fast (rate limit)
- Exceeding the number of feeds for your account (10 currently)
- Sending too large of a payload
Adafruit IO is not a standard MQTT broker. Normally MQTT brokers will rebroadcast published data to any authorized subscribed client as soon as the data is received, so errors are rarely encountered.
The standard MQTT pub/sub workflow looks something like this:
Adafruit IO’s message flow is a bit more complicated, and looks something like this:
In the simplified example above, you can see that there are multiple steps that need to be completed before data is rebroadcasted to subscribed clients. If any of these steps fail, data will not make it back to subscribed clients. The reasons for failure are often unclear to users, so we added two special MQTT topics that will help inform users of any issues related to publishing data.
The first topic you can subscribe to is the error topic for your user. This topic will receive any errors related to data validation and database saves. The topic path looks like this:
{username}/errors
For example, if your username was ladyada
, you would subscribe to the following topic using your favorite MQTT client:
ladyada/errors
The second topic you can subscribe to is the throttle topic for your user. This topic contains any messages related to rate limits on your account. You might see these if you are publishing too fast. The topic path looks like this:
{username}/throttle
Again, if your username was ladyada
, you would subscribe to the following topic:
ladyada/throttle
If you are using the Adafruit MQTT Library, you can define the throttle and error subscriptions at the top of your sketch like this:
/*************************** Error Reporting *********************************/
const char ERRORS[] PROGMEM = AIO_USERNAME "/errors";
Adafruit_MQTT_Subscribe errors = Adafruit_MQTT_Subscribe(&mqtt, ERRORS);
const char THROTTLE[] PROGMEM = AIO_USERNAME "/throttle";
Adafruit_MQTT_Subscribe throttle = Adafruit_MQTT_Subscribe(&mqtt, THROTTLE);
Then, subscribe to the topics at the bottom of the setup
function:
void setup() {
// ...network connection setup code here
// MQTT subscriptions for throttle & error messages
mqtt.subscribe(&throttle);
mqtt.subscribe(&errors);
}
Finally, inside of the main loop
, print any errors to the serial monitor:
void loop() {
// Ensure the connection to the MQTT server is alive (this will make the first
// connection and automatically reconnect when disconnected). See the MQTT_connect
// function definition further below.
MQTT_connect();
// this is our 'wait for incoming subscription packets' busy subloop
// try to spend your time here
Adafruit_MQTT_Subscribe *subscription;
while ((subscription = mqtt.readSubscription(5000))) {
if(subscription == &errors) {
Serial.print(F("ERROR: "));
Serial.println((char *)errors.lastread);
} else if(subscription == &throttle) {
Serial.print(F("THROTTLED: "));
Serial.println((char *)throttle.lastread);
}
}
mqtt.ping();
}
You can see the full example for the ESP8266
in the Adafruit_MQTT Arduino Library on GitHub. Install or update the Adafruit MQTT Library to version 0.13.3
in the Arduino Library Manager, and open the
adafruitio_errors_esp8266
example to get started.
Are these examples helpful? Please visit our IO forum and share your thoughts.