# Buggy code
def raise_sqlite_error(msg, error):
    """Raise either a SqlBugError or SqlKnownError."""
    error_code = error.nativeErrorCode()
    database_text = error.databaseText()
    driver_text = error.driverText()

    log.sql.debug("SQL error:")
    log.sql.debug("type: {}".format(debug.qenum_key(QSqlError, error.type())))
    log.sql.debug("database text: {}".format(database_text))
    log.sql.debug("driver text: {}".format(driver_text))
    log.sql.debug("error code: {}".format(error_code))

    environmental_errors = [
        SqliteErrorCode.BUSY,
        SqliteErrorCode.READONLY,
        SqliteErrorCode.IOERR,
        SqliteErrorCode.CORRUPT,
        SqliteErrorCode.FULL,
        SqliteErrorCode.CANTOPEN,
    ]

    # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-70506
    # We don't know what the actual error was, but let's assume it's not us to
    # blame... Usually this is something like an unreadable database file.
    qtbug_70506 = (
        error_code == SqliteErrorCode.UNKNOWN
        and driver_text == "Error opening database"
        and database_text == "out of memory"
    )

    if (error_code in environmental_errors or qtbug_70506) or (
        error_code == SqliteErrorCode.ERROR
        and driver_text == "Unable to execute statement"
        and database_text.startswith("Expression tree is too large")
    ):
        raise SqlKnownError(msg, error)

    raise SqlBugError(msg, error)


# Traceback (qutebrowser.misc.sql.SqlBugError)
23:32:01 DEBUG    completion completionmodel:set_pattern:179 Setting completion pattern 'x x [...]'
23:32:01 DEBUG    sql        sql:__init__:169 Preparing SQL query: "SELECT url, title, strftime('%Y-%m-%d', last_atime, 'unixepoch', 'localtime') FROM CompletionHistory WHERE ((url || ' ' || title) LIKE :0 escape '\' AND [...] AND (url || ' ' || title) LIKE :9999 escape '\')  ORDER BY last_atime DESC"
23:32:01 DEBUG    sql        sql:raise_sqlite_error:90 SQL error:
23:32:01 DEBUG    sql        sql:raise_sqlite_error:92 type: StatementError
23:32:01 DEBUG    sql        sql:raise_sqlite_error:93 database text: Expression tree is too large (maximum depth 10000)
23:32:01 DEBUG    sql        sql:raise_sqlite_error:94 driver text: Unable to execute statement
23:32:01 DEBUG    sql        sql:raise_sqlite_error:95 error code: 1
23:32:01 DEBUG    completion debug:__exit__:265 Set pattern x x [...] took 0.259335 seconds.
23:32:01 ERROR    misc       crashsignal:exception_hook:214 Uncaught exception
Traceback (most recent call last):
File "/home/florian/proj/qutebrowser/git/qutebrowser/completion/completer.py", line 261, in _update_completion
completion.set_pattern(pattern)
File "/home/florian/proj/qutebrowser/git/qutebrowser/completion/completionwidget.py", line 320, in set_pattern
self.model().set_pattern(pattern)
File "/home/florian/proj/qutebrowser/git/qutebrowser/completion/models/completionmodel.py", line 185, in set_pattern
cat.set_pattern(pattern)
File "/home/florian/proj/qutebrowser/git/qutebrowser/completion/models/histcategory.py", line 99, in set_pattern
]), forward_only=False)
File "/home/florian/proj/qutebrowser/git/qutebrowser/misc/sql.py", line 171, in __init__
self._check_ok('prepare', ok)
File "/home/florian/proj/qutebrowser/git/qutebrowser/misc/sql.py", line 191, in _check_ok
raise_sqlite_error(msg, error)
File "/home/florian/proj/qutebrowser/git/qutebrowser/misc/sql.py", line 115, in raise_sqlite_error
raise SqlBugError(msg, error)
qutebrowser.misc.sql.SqlBugError: Failed to prepare query "SELECT url, title, strftime('%Y-%m-%d', last_atime, 'unixepoch', 'localtime') FROM CompletionHistory WHERE ((url || ' ' || title) LIKE :0 escape '\' AND [...] AND (url || ' ' || title) LIKE :9997 escape '\' AND (url || ' ' || title) LIKE :9998 escape '\' AND (url || ' ' || title) LIKE :9999 escape '\')  ORDER BY last_atime DESC": "Expression tree is too large (maximum depth 10000) Unable to execute statement"

# Fixed code
def raise_sqlite_error(msg, error):
    """Raise either a SqlBugError or SqlKnownError."""
    error_code = error.nativeErrorCode()
    database_text = error.databaseText()
    driver_text = error.driverText()

    log.sql.debug("SQL error:")
    log.sql.debug("type: {}".format(debug.qenum_key(QSqlError, error.type())))
    log.sql.debug("database text: {}".format(database_text))
    log.sql.debug("driver text: {}".format(driver_text))
    log.sql.debug("error code: {}".format(error_code))

    environmental_errors = [
        SqliteErrorCode.BUSY,
        SqliteErrorCode.READONLY,
        SqliteErrorCode.IOERR,
        SqliteErrorCode.CORRUPT,
        SqliteErrorCode.FULL,
        SqliteErrorCode.CANTOPEN,
    ]

    # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-70506
    # We don't know what the actual error was, but let's assume it's not us to
    # blame... Usually this is something like an unreadable database file.
    qtbug_70506 = (
        error_code == SqliteErrorCode.UNKNOWN
        and driver_text == "Error opening database"
        and database_text == "out of memory"
    )

    # https://github.com/qutebrowser/qutebrowser/issues/4681
    # If the query we built was too long
    too_long_err = (
        error_code == SqliteErrorCode.ERROR
        and driver_text == "Unable to execute statement"
        and (
            database_text.startswith("Expression tree is too large")
            or database_text == "too many SQL variables"
        )
    )

    if error_code in environmental_errors or qtbug_70506 or too_long_err:
        raise SqlKnownError(msg, error)

    raise SqlBugError(msg, error)