Catch MQTT encoding errors (#3749)

* added error handling to mqtt message receive if payload is not utf-8 unicode
added mqtt test for above code as well

* change permission back to 644

* attempting to test new code

* changed exception to AttributeError
fixed test for above

* fixed lint errors I made in tests....mqtt/test_init.py

* more lint fixes for my added test

* remove dual decode of MQTT payload

* convert if to try, except, else statement for mqtt payload decode

* rework mqtt unicode testing code to properly check for log file entriy on unicode decode exception

* fixed lint error

* Update test_init.py
pull/3873/merge
Michael 2016-10-14 21:08:44 -07:00 committed by Paulus Schoutsen
parent 180e146e14
commit ce19e6367f
2 changed files with 38 additions and 7 deletions

View File

@ -401,13 +401,20 @@ class MQTT(object):
def _mqtt_on_message(self, _mqttc, _userdata, msg):
"""Message received callback."""
_LOGGER.debug("received message on %s: %s",
msg.topic, msg.payload.decode('utf-8'))
self.hass.bus.fire(EVENT_MQTT_MESSAGE_RECEIVED, {
ATTR_TOPIC: msg.topic,
ATTR_QOS: msg.qos,
ATTR_PAYLOAD: msg.payload.decode('utf-8'),
})
try:
payload = msg.payload.decode('utf-8')
except AttributeError:
_LOGGER.error("Illegal utf-8 unicode payload from "
"MQTT topic: %s, Payload: %s", msg.topic,
msg.payload)
else:
_LOGGER.debug("received message on %s: %s",
msg.topic, payload)
self.hass.bus.fire(EVENT_MQTT_MESSAGE_RECEIVED, {
ATTR_TOPIC: msg.topic,
ATTR_QOS: msg.qos,
ATTR_PAYLOAD: payload,
})
def _mqtt_on_unsubscribe(self, _mqttc, _userdata, mid, granted_qos):
"""Unsubscribe successful callback."""

View File

@ -316,3 +316,27 @@ class TestMQTTCallbacks(unittest.TestCase):
def test_invalid_mqtt_topics(self):
self.assertRaises(vol.Invalid, mqtt.valid_publish_topic, 'bad+topic')
self.assertRaises(vol.Invalid, mqtt.valid_subscribe_topic, 'bad\0one')
def test_receiving_non_utf8_message_gets_logged(self):
"""Test receiving a non utf8 encoded message."""
calls = []
def record(event):
"""Helper to record calls."""
calls.append(event)
payload = 0x9a
topic = 'test_topic'
self.hass.bus.listen_once(mqtt.EVENT_MQTT_MESSAGE_RECEIVED, record)
MQTTMessage = namedtuple('MQTTMessage', ['topic', 'qos', 'payload'])
message = MQTTMessage(topic, 1, payload)
with self.assertLogs(level='ERROR') as test_handle:
mqtt.MQTT_CLIENT._mqtt_on_message(
None,
{'hass': self.hass},
message)
self.hass.block_till_done()
self.assertIn(
"ERROR:homeassistant.components.mqtt:Illegal utf-8 unicode "
"payload from MQTT topic: %s, Payload: " % topic,
test_handle.output[0])