def raise_sqlite_error(msg: str, error: QSqlError) -> None: """Raise either a BugError or KnownError.""" error_code = error.nativeErrorCode() database_text = error.databaseText() driver_text = error.driverText() log.sql.debug("SQL error:") log.sql.debug(f"type: {debug.qenum_key(QSqlError, error.type())}") log.sql.debug(f"database text: {database_text}") log.sql.debug(f"driver text: {driver_text}") log.sql.debug(f"error code: {error_code}") known_errors = [ SqliteErrorCode.BUSY, SqliteErrorCode.READONLY, SqliteErrorCode.IOERR, SqliteErrorCode.CORRUPT, SqliteErrorCode.FULL, SqliteErrorCode.CANTOPEN, SqliteErrorCode.PROTOCOL, SqliteErrorCode.NOTADB, ] # https://github.com/qutebrowser/qutebrowser/issues/4681 # If the query we built was too long too_long_err = ( error_code == SqliteErrorCode.ERROR and (database_text.startswith("Expression tree is too large") or database_text in ["too many SQL variables", "LIKE or GLOB pattern too complex"])) if error_code in known_errors or too_long_err: raise KnownError(msg, error) raise BugError(msg, error)
def _check_error(err: QSqlError): if not err.isValid(): return False elif err.type() == QtSql.QSqlError.TransactionError: raise Exception(f"Transaction error: {err.text()}") elif err.type() == QtSql.QSqlError.StatementError: raise Exception(f"Statement error: {err.text()}") else: raise Exception(f"Unknown error: {err.text()}")
def test_from_query(self): sql_err = QSqlError("driver text", "db text") err = sql.SqliteError.from_query( what='test', query='SELECT * from foo;', error=sql_err) expected = ('Failed to test query "SELECT * from foo;": ' '"db text driver text"') assert str(err) == expected
def addConnection(self, driver, dbName, user, password, host, port): """ Public method to add a database connection. @param driver name of the Qt database driver (string) @param dbName name of the database (string) @param user user name (string) @param password password (string) @param host host name (string) @param port port number (integer) @return SQL error object (QSqlError) """ err = QSqlError() self.__class__.cCount += 1 db = QSqlDatabase.addDatabase( driver.upper(), "Browser{0:d}".format(self.__class__.cCount)) db.setDatabaseName(dbName) db.setHostName(host) db.setPort(port) if not db.open(user, password): err = db.lastError() db = QSqlDatabase() QSqlDatabase.removeDatabase("Browser{0:d}".format( self.__class__.cCount)) self.connections.refresh() return err
def test_qtbug_70506(self): """Test Qt's wrong handling of errors while opening the database. Due to https://bugreports.qt.io/browse/QTBUG-70506 we get an error with "out of memory" as string and -1 as error code. """ sql_err = QSqlError("Error opening database", "out of memory", QSqlError.UnknownError, sql.SqliteErrorCode.UNKNOWN) with pytest.raises(sql.KnownError): sql.raise_sqlite_error("Message", sql_err)
def test_logging(self, caplog): sql_err = QSqlError("driver text", "db text", QSqlError.UnknownError, '23') sql.SqliteError("Message", sql_err) lines = [r.message for r in caplog.records] expected = [ 'SQL error:', 'type: UnknownError', 'database text: db text', 'driver text: driver text', 'error code: 23' ] assert lines == expected
def test_logging(self, caplog): sql_err = QSqlError("driver text", "db text", QSqlError.UnknownError, '23') with pytest.raises(sql.BugError): sql.raise_sqlite_error("Message", sql_err) expected = [ 'SQL error:', 'type: UnknownError', 'database text: db text', 'driver text: driver text', 'error code: 23' ] assert caplog.messages == expected
def handle_sql_error(self, error: QSqlError = None): """ Types: ConnectionError = 1 NoError = 0 StatementError = 2 TransactionError = 3 UnknownError = 4 :param error: :return: """ if error is not None: if error.type() == QSqlError.NoError: pass elif error.type() == QSqlError.ConnectionError: Log.e("SQL Error [Connection Error] - %s" % error.text()) elif error.type() == QSqlError.StatementError: Log.e("SQL Error [Statement Error] - %s" % error.text()) elif error.type() == QSqlError.TransactionError: Log.e("SQL Error [Transaction Error] - %s" % error.text()) else: Log.e("SQL Error [Unknown Error] - %s" % error.text())
def test_known(self, error_code, exception): sql_err = QSqlError("driver text", "db text", QSqlError.UnknownError, error_code) with pytest.raises(exception): sql.raise_sqlite_error("Message", sql_err)
def test_text(self, klass): sql_err = QSqlError("driver text", "db text") err = klass("Message", sql_err) assert err.text() == "db text"
def test_text(self): sql_err = QSqlError("driver text", "db text") err = sql.SqliteError("Message", sql_err) assert err.text() == "db text"
def test_subclass(self): with pytest.raises(sql.SqlError): raise sql.SqliteError("text", QSqlError())
def test_environmental(self, error_code, environmental): sql_err = QSqlError("driver text", "db text", QSqlError.UnknownError, error_code) err = sql.SqliteError("Message", sql_err) assert err.environmental == environmental
def lastError(self): return QSqlError()