javascripttypescriptindexeddbdexie

silent error "UpgradeError Not yet support for changing primary key" in useLiveQuery() in Dexie


I was not aware that it was not possible to change primary key in Dexie and it gave me this error:

UpgradeError Not yet support for changing primary key

But my main issue is that this error is silent in useLiveQuery():

  useLiveQuery(
   () => db.tournaments.limit(5).reverse().toArray(),
   [],
    "loading",
  );

  useEffect(() => {
    window.addEventListener("unhandledrejection", (event) => {
      console.error(event); // This doesn't work. no error event
    });
  }, []);


Since it is silent, my custom ErrorBoundary cannot be triggered unless I catch this error in every useLiveQuery().

useLiveQuery(
    () => {
        try{
          db.tournaments.limit(5).reverse().toArray()
        }catch(e){
          throw new Error("DB error")
        }
     }
    [],
    "loading",
  );


I think this error is caught in dexie.js from line 1274:

       Table.prototype._trans = function (mode, fn, writeLocked) {
            var trans = this._tx || PSD.trans;
            var tableName = this.name;
            var task = debug && typeof console !== 'undefined' && console.createTask && console.createTask("Dexie: ".concat(mode === 'readonly' ? 'read' : 'write', " ").concat(this.name));
            function checkTableInTransaction(resolve, reject, trans) {
                if (!trans.schema[tableName])
                    throw new exceptions.NotFound("Table " + tableName + " not part of transaction");
                return fn(trans.idbtrans, trans);
            }
            var wasRootExec = beginMicroTickScope();
            try {
                var p = trans && trans.db._novip === this.db._novip ?
                    trans === PSD.trans ?
                        trans._promise(mode, checkTableInTransaction, writeLocked) :
                        newScope(function () { return trans._promise(mode, checkTableInTransaction, writeLocked); }, { trans: trans, transless: PSD.transless || PSD }) :
                    tempTransaction(this.db, mode, [this.name], checkTableInTransaction);
                if (task) {
                    p._consoleTask = task;
                    p = p.catch(function (err) {
                        console.trace(err); <<<===== HERE
                        return rejection(err);
                    });
                }
                return p;
            }
            finally {
                if (wasRootExec)
                    endMicroTickScope();
            }
        };

enter image description here

Is this DatabaseClosedError error supposed to be silent in useLiveQuery()?


Solution

  • The first time any Dexie query is executed, it will need to open the database unless the application has already done that. During the opening of the database, the versions and schemas are being compared to the persisted database on the device. In this case, it seems as the schema has been changed after having been created and that the change involves changing the primary key property, which is not supported.

    If you want to catch the UpgradeError earlier in your app, do an explicit call to await db.open() in your application bootstrapping code (not nescessarily within a React component).

    If the application hasn't been released yet, just go to devtools --> Applications tab --> IndexedDB and delete the database and your issue should be gone.

    If you on the other hand is trying to change the primary key and already have users that have previous versions of your database installed, you might need to change the table name, see https://github.com/dexie/Dexie.js/issues/646#issuecomment-359755452