From 12129f0e6a7d02f9ab44a291d8ee1d48d4ca02ab Mon Sep 17 00:00:00 2001 From: Sean Date: Fri, 7 Jul 2017 06:46:50 +0200 Subject: [PATCH] Try catch around database updates in recorder. Resolves 6919 (#8349) * Try catch around database updates in recorder. Resolves 6919 * Fixing failed test for line length * Catch only OperationalError and retry connections before giving up * Including alchemy exceptions in single function --- homeassistant/components/recorder/__init__.py | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/recorder/__init__.py b/homeassistant/components/recorder/__init__.py index 49af353aab8..63dbf9fc1b1 100644 --- a/homeassistant/components/recorder/__init__.py +++ b/homeassistant/components/recorder/__init__.py @@ -158,6 +158,7 @@ class Recorder(threading.Thread): """Start processing events to save.""" from .models import States, Events from homeassistant.components import persistent_notification + from sqlalchemy import exc tries = 1 connected = False @@ -273,14 +274,31 @@ class Recorder(threading.Thread): self.queue.task_done() continue - with session_scope(session=self.get_session()) as session: - dbevent = Events.from_event(event) - session.add(dbevent) + tries = 1 + updated = False + while not updated and tries <= 10: + if tries != 1: + time.sleep(CONNECT_RETRY_WAIT) + try: + with session_scope(session=self.get_session()) as session: + dbevent = Events.from_event(event) + session.add(dbevent) - if event.event_type == EVENT_STATE_CHANGED: - dbstate = States.from_event(event) - dbstate.event_id = dbevent.event_id - session.add(dbstate) + if event.event_type == EVENT_STATE_CHANGED: + dbstate = States.from_event(event) + dbstate.event_id = dbevent.event_id + session.add(dbstate) + updated = True + + except exc.OperationalError as err: + _LOGGER.error("Error in database connectivity: %s. " + "(retrying in %s seconds)", err, + CONNECT_RETRY_WAIT) + tries += 1 + + if not updated: + _LOGGER.error("Error in database update. Could not save " + "after %d tries. Giving up", tries) self.queue.task_done()