From f8eb545aa0b268cfd08644b0996a6681359dc0bc Mon Sep 17 00:00:00 2001 From: Devan Franchini Date: Mon, 29 Feb 2016 01:09:27 -0500 Subject: Adds error reporting for db read failures If the database back-end fails to be read then layman will properly report it and exit without causing an ugly traceback. --- layman/db_modules/json_db/json_db.py | 7 +- layman/db_modules/sqlite_db/sqlite_db.py | 121 +++++++++++++++++-------------- layman/db_modules/xml_db/xml_db.py | 21 ++++-- layman/dbbase.py | 12 ++- 4 files changed, 95 insertions(+), 66 deletions(-) diff --git a/layman/db_modules/json_db/json_db.py b/layman/db_modules/json_db/json_db.py index 70e41d5..bf88593 100644 --- a/layman/db_modules/json_db/json_db.py +++ b/layman/db_modules/json_db/json_db.py @@ -75,6 +75,10 @@ class DBHandler(object): try: with fileopen(path, 'r') as df: document = df.read() + except ValueError as error: + msg = 'JSON DBHanlder - ValueError: %(err)s' % {'err': error} + self.output.error(msg) + return False except Exception as error: if not self.ignore_init_read_errors: msg = 'JSON DBHandler - Failed to read the overlay list at'\ @@ -82,7 +86,8 @@ class DBHandler(object): self.output.error(msg) raise error - self.add_new(document, origin=path) + success = self.add_new(document, origin=path) + return success def add_new(self, document=None, origin=None): diff --git a/layman/db_modules/sqlite_db/sqlite_db.py b/layman/db_modules/sqlite_db/sqlite_db.py index a3305a7..3585c4a 100644 --- a/layman/db_modules/sqlite_db/sqlite_db.py +++ b/layman/db_modules/sqlite_db/sqlite_db.py @@ -136,6 +136,8 @@ class DBHandler(object): CONFLICT IGNORE )''') connection.commit() + except sqlite3.DatabaseError as err: + raise err except Exception as err: msg = 'SQLite DBHandler error; failed to create database.\n'\ 'Error was: %(msg)s' % {'msg': err} @@ -152,64 +154,71 @@ class DBHandler(object): overlay_id = None overlay = {} - with self.__connect__(path) as connection: - cursor = connection.cursor() - cursor.execute('''SELECT Overlay_ID, Name, Priority, Status, - Quality, Homepage, IRC, License FROM Overlay''') - overlays_info = cursor.fetchall() - connection.commit() + try: + connection = self.__connect__(path) + except sqlite3.DatabaseError as err: + msg = 'SQLite DBHandler DatabaseError: %(err)s' % {'err': err} + self.output.error(msg) + return False - for overlay_info in overlays_info: - overlay = {} - overlay_id = overlay_info[0] - overlay['name'] = overlay_info[1] - - cursor.execute('''SELECT URL, Type, Branch FROM Overlay_Source - JOIN Overlay USING (Overlay_ID) JOIN Source USING (Source_ID) - WHERE Overlay_ID = ?''', (overlay_id,)) - overlay['source'] = cursor.fetchall() - - cursor.execute('''SELECT Owner_Email, Owner_Name FROM - Overlay_Owner JOIN Overlay USING (Overlay_ID) JOIN Owner USING - (Owner_ID) WHERE Overlay_ID = ?''', (overlay_id,)) - owner_info = cursor.fetchall() - overlay['owner'] = [] - - for _owner in owner_info: - owner = {} - if _owner[0]: - owner['email'] = _owner[0] + cursor = connection.cursor() + cursor.execute('''SELECT Overlay_ID, Name, Priority, Status, + Quality, Homepage, IRC, License FROM Overlay''') + overlays_info = cursor.fetchall() + connection.commit() + + for overlay_info in overlays_info: + overlay = {} + overlay_id = overlay_info[0] + overlay['name'] = overlay_info[1] + + cursor.execute('''SELECT URL, Type, Branch FROM Overlay_Source + JOIN Overlay USING (Overlay_ID) JOIN Source USING (Source_ID) + WHERE Overlay_ID = ?''', (overlay_id,)) + overlay['source'] = cursor.fetchall() + + cursor.execute('''SELECT Owner_Email, Owner_Name FROM Overlay_Owner + JOIN Overlay USING (Overlay_ID) JOIN Owner USING (Owner_ID) + WHERE Overlay_ID = ?''', (overlay_id,)) + owner_info = cursor.fetchall() + overlay['owner'] = [] + for _owner in owner_info: + owner = {} + if _owner[0]: + owner['email'] = _owner[0] + else: + owner['email'] = None + if len(_owner) > 1: + if _owner[1]: + owner['name'] = _owner[1] else: - owner['email'] = None - if len(_owner) > 1: - if _owner[1]: - owner['name'] = _owner[1] - else: - owner['name'] = None - overlay['owner'].append(owner) - - cursor.execute('''SELECT Description FROM Description JOIN - Overlay USING (Overlay_ID) WHERE Overlay_ID = ?''', - (overlay_id,)) - overlay['description'] = cursor.fetchall()[0] - - overlay['status'] = overlay_info[3] - overlay['quality'] = overlay_info[4] - overlay['priority'] = overlay_info[2] - overlay['license'] = overlay_info[7] - overlay['homepage'] = overlay_info[5] - overlay['IRC'] = overlay_info[6] - - cursor.execute('''SELECT Feed FROM Feed JOIN Overlay USING - (Overlay_ID) WHERE Overlay_ID = ?''', (overlay_id,)) - overlay['feed'] = cursor.fetchall() - - if len(overlay['feed']): - overlay['feed'] = overlay['feed'][0] - - self.overlays[overlay_info[1]] = Overlay(self.config, - ovl_dict=overlay, - ignore=self.ignore) + owner['name'] = None + overlay['owner'].append(owner) + + cursor.execute('''SELECT Description FROM Description + JOIN Overlay USING (Overlay_ID) WHERE Overlay_ID = ?''', + (overlay_id,)) + overlay['description'] = cursor.fetchall()[0] + + overlay['status'] = overlay_info[3] + overlay['quality'] = overlay_info[4] + overlay['priority'] = overlay_info[2] + overlay['license'] = overlay_info[7] + overlay['homepage'] = overlay_info[5] + overlay['IRC'] = overlay_info[6] + + cursor.execute('''SELECT Feed FROM Feed JOIN Overlay USING + (Overlay_ID) WHERE Overlay_ID = ?''', (overlay_id,)) + overlay['feed'] = cursor.fetchall() + + if len(overlay['feed']): + overlay['feed'] = overlay['feed'][0] + + self.overlays[overlay_info[1]] = Overlay(self.config, + ovl_dict=overlay, + ignore=self.ignore) + connection.close() + return True def add_new(self, document=None, origin=None): diff --git a/layman/db_modules/xml_db/xml_db.py b/layman/db_modules/xml_db/xml_db.py index fbd7a6a..f44b9c5 100644 --- a/layman/db_modules/xml_db/xml_db.py +++ b/layman/db_modules/xml_db/xml_db.py @@ -108,12 +108,13 @@ class DBHandler(object): document = df.read() except Exception as error: if not self.ignore_init_read_errors: - msg = 'XML DBHandler - Failed to read the overlay list at'\ - '("%(path)s")' % {'path': path} + msg = 'XML DBHandler - Failed to read the overlay list at '\ + '"%(path)s"' % {'path': path} self.output.error(msg) - raise error + return False - self.read(document, origin=path) + success = self.read(document, origin=path) + return success def read(self, text, origin): @@ -123,8 +124,10 @@ class DBHandler(object): ''' try: document = ET.fromstring(text) - except xml.parsers.expat.ExpatError as err: - raise BrokenOverlayCatalog(origin, err, self._broken_catalog_hint()) + except ET.ParseError as error: + msg = 'XML DBHandler - ET.ParseError: %(err)s' % {'err': error} + self.output.error(msg) + return False overlays = document.findall('overlay') + document.findall('repo') @@ -134,6 +137,8 @@ class DBHandler(object): ovl = Overlay(config=self.config, xml=overlay, ignore=self.ignore) self.overlays[ovl.name] = ovl + return True + def add_new(self, xml=None, origin=None): ''' @@ -145,8 +150,8 @@ class DBHandler(object): self.output.warn(msg) return False - self.read(xml, origin) - return True + success = self.read(xml, origin) + return success def remove(self, overlay, path): diff --git a/layman/dbbase.py b/layman/dbbase.py index c2b25b8..8b25fcd 100644 --- a/layman/dbbase.py +++ b/layman/dbbase.py @@ -111,7 +111,17 @@ class DbBase(object): if not os.path.exists(path): continue - self.read_db(path) + success = self.read_db(path) + if not success: + msg = 'DbBase; error, Failed to read database at "%(path)s"\n'\ + 'Hint: If you manually set db_type. Please reset it and '\ + 'let layman-updater\nmigrate it. Otherwise layman\'s '\ + 'database is not initialized, nor populated\nwith any '\ + 'existing data.\nRun the following: "layman-updater -m '\ + '"' % {'path': path} + self.output.error(msg) + sys.exit(-1) + path_found = True if not path_found and not allow_missing: -- cgit v1.2.3-65-gdbad