diff --git a/beets/dbcore/db.py b/beets/dbcore/db.py index 6b0ed8b43e..ef7231a762 100755 --- a/beets/dbcore/db.py +++ b/beets/dbcore/db.py @@ -33,6 +33,15 @@ import six +class DBAccessError(Exception): + """The SQLite database became inaccessible. + + This can happen when trying to read or write the database when, for + example, the database file is deleted or otherwise disappears. There + is probably no way to recover from this error. + """ + + class FormattedMapping(collections.Mapping): """A `dict`-like formatted view of a model. @@ -680,8 +689,18 @@ def mutate(self, statement, subvals=()): """Execute an SQL statement with substitution values and return the row ID of the last affected row. """ - cursor = self.db._connection().execute(statement, subvals) - return cursor.lastrowid + try: + cursor = self.db._connection().execute(statement, subvals) + return cursor.lastrowid + except sqlite3.OperationalError as e: + # In two specific cases, SQLite reports an error while accessing + # the underlying database file. We surface these exceptions as + # DBAccessError so the application can abort. + if e.args[0] in ("attempt to write a readonly database", + "unable to open database file"): + raise DBAccessError(e.args[0]) + else: + raise def script(self, statements): """Execute a string containing multiple SQL statements.""" diff --git a/beets/ui/__init__.py b/beets/ui/__init__.py index 75bce9e7a7..60652fa08a 100644 --- a/beets/ui/__init__.py +++ b/beets/ui/__init__.py @@ -41,6 +41,7 @@ from beets.util import confit, as_string from beets.autotag import mb from beets.dbcore import query as db_query +from beets.dbcore import db import six # On Windows platforms, use colorama to support "ANSI" terminal colors. @@ -1253,3 +1254,10 @@ def main(args=None): except KeyboardInterrupt: # Silently ignore ^C except in verbose mode. log.debug(u'{}', traceback.format_exc()) + except db.DBAccessError as exc: + log.error( + u'database access error: {0}\n' + u'the library file might have a permissions problem', + exc + ) + sys.exit(1) diff --git a/docs/changelog.rst b/docs/changelog.rst index 274f366654..537270d48c 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -88,6 +88,8 @@ Fixes: AAC codec instead of faac. Thanks to :user:`jansol`. :bug:`2484` * Fix import of multidisc releases with subdirectories, which previously made each disc be imported separately in different releases. :bug:`2493` +* When the SQLite database stops being accessible, we now print a friendly + error message. Thanks to :user:`Mary011196`. :bug:`1676` :bug:`2508` 1.4.3 (January 9, 2017)