From f81a489640ad356d83ff377ddd4fcb45754b748b Mon Sep 17 00:00:00 2001 From: Christian Fetzer Date: Sun, 25 Mar 2018 18:17:27 +0200 Subject: [PATCH] fritzcollectd: Recover from XMLSyntaxError in read callback In rare cases reading from the FRITZ!Box can trigger XMLSyntaxError exceptions (for example: 'Opening and ending tag mismatch: HR line 1 and BODY, line 1, column 180 (line 1)'. If this happens the connection seems to be unusable and the error would happen also on subsequent calls. Reinitialize the connection if this happens. This has been reported for a FRITZ!Box 6490 (6.52) when the device is remotely reset by Unitymedia. See #12. --- fritzcollectd.py | 9 +++++++-- test_fritzcollectd.py | 10 ++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/fritzcollectd.py b/fritzcollectd.py index 9d1bf84..74883c2 100644 --- a/fritzcollectd.py +++ b/fritzcollectd.py @@ -29,7 +29,7 @@ import collectd # pylint: disable=import-error -__version__ = '0.5.0' +__version__ = '0.5.1' CONFIGS = [] @@ -261,7 +261,12 @@ def callback_init(): def callback_read(): """ Read callback """ for config in CONFIGS: - config.read() + try: + config.read() + except XMLSyntaxError: + collectd.warning('fritzcollectd: Invalid data received, ' + 'attempting to reconnect') + config.init() def callback_shutdown(): diff --git a/test_fritzcollectd.py b/test_fritzcollectd.py index c56fde0..375f19c 100644 --- a/test_fritzcollectd.py +++ b/test_fritzcollectd.py @@ -281,6 +281,16 @@ def test_incorrect_password(fc_class_mock): MOCK.process(CollectdConfig({'Password': 'incorrect'})) +@mock.patch('fritzconnection.FritzConnection', autospec=True) +@with_setup(teardown=MOCK.reset_mock) +def test_xmlsyntaxerror_in_read(fc_class_mock): + """ Simulate an XMLSyntaxError exception when reading data. """ + fc_mock = FritzConnectionMock() + fc_class_mock.return_value = fc_mock + fc_mock.call_action.side_effect = [{0}, XMLSyntaxError(0, 0, 0, 0), {0}] + MOCK.process() + + # System tests that try to interact with a real hardware device. @nottest