diff --git a/lib/extension/frontend.ts b/lib/extension/frontend.ts index 99ed40534..d2a6701a1 100644 --- a/lib/extension/frontend.ts +++ b/lib/extension/frontend.ts @@ -163,8 +163,13 @@ export class Frontend extends Extension { ws.on("message", (data: Buffer, isBinary: boolean) => { if (!isBinary && data) { const message = data.toString(); - const {topic, payload} = JSON.parse(message); - this.mqtt.onMessage(`${this.mqttBaseTopic}/${topic}`, Buffer.from(stringify(payload))); + + try { + const {topic, payload} = JSON.parse(message); + this.mqtt.onMessage(`${this.mqttBaseTopic}/${topic}`, Buffer.from(stringify(payload))); + } catch { + logger.error(`Received invalid message from WebSocket: ${message}`); + } } }); diff --git a/test/extensions/frontend.test.ts b/test/extensions/frontend.test.ts index 5323b2871..e21673d66 100644 --- a/test/extensions/frontend.test.ts +++ b/test/extensions/frontend.test.ts @@ -262,6 +262,12 @@ describe("Extension: Frontend", () => { mockWSClientEvents.message(null, false); await flushPromises(); + // Malformed payload, must not escape the listener + mockLogger.error.mockClear(); + expect(() => mockWSClientEvents.message("not json", false)).not.toThrow(); + expect(mockLogger.error).toHaveBeenCalledWith("Received invalid message from WebSocket: not json"); + await flushPromises(); + // Error mockWSClientEvents.error(new Error("This is an error")); expect(mockLogger.error).toHaveBeenCalledWith("WebSocket error: This is an error");