diff --git a/lib/extension/frontend.js b/lib/extension/frontend.js index a7d733ced0..b7b481b6f1 100644 --- a/lib/extension/frontend.js +++ b/lib/extension/frontend.js @@ -80,8 +80,10 @@ class Frontend extends Extension { onWebSocketConnection(ws) { ws.on('message', (message) => { - const {topic, payload} = utils.parseJSON(message, message); - this.mqtt.onMessage(`${this.mqttBaseTopic}/${topic}`, stringify(payload)); + if (message) { + const {topic, payload} = utils.parseJSON(message, message); + this.mqtt.onMessage(`${this.mqttBaseTopic}/${topic}`, stringify(payload)); + } }); for (const [key, value] of this.retainedMessages) { diff --git a/lib/extension/publish.js b/lib/extension/publish.js index f13446c24e..130f0ffe20 100644 --- a/lib/extension/publish.js +++ b/lib/extension/publish.js @@ -125,10 +125,14 @@ class EntityPublish extends Extension { json = {state: message}; } else { logger.error(`Invalid JSON '${message}', skipping...`); + return false; } } } - + if (!json) { + logger.error(`Invalid JSON '${message}', skipping...`); + return; + } /** * Home Assistant always publishes 'state', even when e.g. only setting diff --git a/lib/mqtt.js b/lib/mqtt.js index ea6a791c30..b00d5501d9 100644 --- a/lib/mqtt.js +++ b/lib/mqtt.js @@ -91,7 +91,7 @@ class MQTT extends events.EventEmitter { } onMessage(topic, message) { - this.emit('message', {topic, message: message.toString()}); + this.emit('message', {topic, message: message + ''}); } isConnected() { diff --git a/test/frontend.test.js b/test/frontend.test.js index 5032547c53..ff58e25cc6 100644 --- a/test/frontend.test.js +++ b/test/frontend.test.js @@ -139,6 +139,10 @@ describe('Frontend', () => { { retain: false, qos: 0 }, expect.any(Function) ); + mockWSClient.events.message(undefined); + mockWSClient.events.message(""); + mockWSClient.events.message(null); + await flushPromises(); // Received message on socket expect(mockWSClient.implementation.send).toHaveBeenCalledTimes(4); diff --git a/test/publish.test.js b/test/publish.test.js index 8dfe4c3170..1eeaf3a02a 100644 --- a/test/publish.test.js +++ b/test/publish.test.js @@ -66,6 +66,18 @@ describe('Publish', () => { expect(MQTT.publish.mock.calls[0][2]).toStrictEqual({"qos": 0, "retain": false}); }); + it('Should corretly handle mallformed messages', async () => { + await MQTT.events.message('zigbee2mqtt/foo', undefined); + await MQTT.events.message('zigbee2mqtt/foo', null); + await MQTT.events.message('zigbee2mqtt/foo', ""); + + await MQTT.events.message('zigbee2mqtt/bulb_color/set', undefined); + await MQTT.events.message('zigbee2mqtt/bulb_color/set', null); + await MQTT.events.message('zigbee2mqtt/bulb_color/set', ""); + await flushPromises(); + expectNothingPublished(); + }); + it('Should publish messages to zigbee devices when there is no converters', async () => { await MQTT.events.message('zigbee2mqtt/bulb_color/set', stringify({brightness_no: '200'})); await flushPromises();