Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OperationalError from SQlite that indicates a permissions problem. #2508

Merged
merged 12 commits into from Apr 19, 2017
13 changes: 10 additions & 3 deletions beets/dbcore/db.py
Expand Up @@ -32,6 +32,10 @@
from .query import MatchQuery, NullSort, TrueQuery
import six

class AccessFileError(Exception):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about "DBAccessError" for clarity?

"""UI exception. Commands should throw this in order to display
nonrecoverable errors to the user.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like the description for UserError? Here's an alternative docstring:

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.
Expand Down Expand Up @@ -680,14 +684,17 @@ 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:
raise AccessFileError("unable to open database file. It might be a permissions problem")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is where the check for error strings like "attempt to write a readonly database" should occur. (For what it's worth, I did a little experiment—that's the message that appears if I try to access the database after deleting the file from my disk!)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, i have to add an if that check if e.args[0] is equals with "attempt to write a readonly database file" and another that checks if e.args[0] is equals with "unable to open database file"? I already tried it and when the message is "unable to open database file" it gives me again the message of UserError.

Thank you!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep! Or we can just have one if that checks whether it's either of those things:

if e.args[0] in ('string1', 'string2'):

I don't quite understand what you mean about the UserError… is some other code producing a UserError exception?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello,
I think i fixed it. Is it right?
Thank you!!



def script(self, statements):
"""Execute a string containing multiple SQL statements."""
self.db._connection().executescript(statements)


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it seems small, but we need this blank line here for consistency.

class Database(object):
"""A container for Model objects that wraps an SQLite database as
the backend.
Expand Down
4 changes: 4 additions & 0 deletions beets/ui/__init__.py
Expand Up @@ -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.
Expand Down Expand Up @@ -1247,3 +1248,6 @@ def main(args=None):
except KeyboardInterrupt:
# Silently ignore ^C except in verbose mode.
log.debug(u'{}', traceback.format_exc())
except db.AccessFileError as exc:
log.error(u'{0}',exc)
sys.exit(1)