jakearchibald / idb

IndexedDB, but with promises
https://www.npmjs.com/package/idb
ISC License
6.22k stars 348 forks source link

'Unknown Error' when opening IDB in Firefox #228

Open angiedemarc opened 3 years ago

angiedemarc commented 3 years ago

I have discovered an 'Unknown Error' that causes the webpage to crash upon opening the database in some Firefox browsers. I believe it's related to this Firefox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1246615 which I found from this Stack overflow page (also describing the issue): https://stackoverflow.com/questions/46553473/unknownerror-on-indexeddb-open-in-firefox

The solution proposed in the stack overflow article above is to add this to the code when opening the database:

DBOpenRequest.onerror = function(event) {
// error handling
};

Some context on what I am doing:

I'm opening the database by calling 'openDB' and passing in the database name, version, and upgrade parameters. From looking at the code, it seems like there is already error handling in place - specifically in 'promisifyRequest' with: request.addEventListener('error', error);

Additionally, I have catches in place in my code with a try/catch that looks something like the following:

try {
    openDBPromise = openDB<SchemaName>(dbName, 1, {
        upgrade: (db) => {
            //logic
        },
    }).then((db) => {
        if (!db) {
            throw new Error('No database returned from openDB request');
        }
        return db;
    });
} catch (err) {
    //error handling logic
}

I also have .catch() in place after use of 'openDBPromise' in other parts of the code.

Between all this error handling logic, I'm not sure how this is still causing the page to crash. I'm hoping somebody can provide insight to this problem!

jakearchibald commented 3 years ago

I have discovered an 'Unknown Error' that causes the webpage to crash

What kind of crash are we talking about here? A full tab/browser crash?

I believe it's related to this Firefox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1246615

Hah, yeah, I've been bitten by this bug before https://bugzilla.mozilla.org/show_bug.cgi?id=1246615#c51. Have you downgraded Firefox to an earlier version, or do you switch between builds using the same profile?

Additionally, I have catches in place in my code with a try/catch that looks something like the following:

try/catch doesn't work for promises unless you await the promise. So:

async function demo() {
  let db;
  try {
    db = await openDB(/* … */);
  } catch (err) {
    // …
  }
}

Between all this error handling logic, I'm not sure how this is still causing the page to crash

If it's a full tab/browser crash, then something is going wrong with the browser, and I'm not sure it can be prevented with JavaScript. It shouldn't really be possible to crash a tab from JavaScript, aside from infinite loops & out-of-memory issues, neither of which are happening here.

If it only happens to users that are running an old browser against a newer profile, I think the only answer is "don't do that". After I ran into that issue I started using separate profiles for the different Firefox versions I run.

angiedemarc commented 3 years ago

This is causing the page to crash, not the entire browser. Hadn't noticed your comment on the thread haha - glad to hear you're familiar with the issue. Thanks for pointing out the try/catch -- I believe the .catch() I had in other places in the code should have still caught any errors.

Unfortunately, I don't have control over what browser version my code is running in/what profile people are using, so that's not a viable solution for me. Would you consider implementing the solution from the Stack Overflow page to prevent users who are using an old browser with a new profile from encountering this crash? Would the 'onerror' provide any added protection from what's already there?

jakearchibald commented 3 years ago

Unfortunately the thing on Stack Overflow doesn't solve the issue. This library already attaches an error handler to the open request. https://github.com/jakearchibald/idb/blob/main/src/wrap-idb-value.ts#L64

If it's a full tab crash (as in the whole page is replaced with an error page), I'm not sure it's solvable with JavaScript.

jakearchibald commented 3 years ago

If you want to experiment with setting things on the IDBOpenRequest yourself, you can use unwrap:

import { openDB, unwrap } from 'idb';

const openPromise = openDB(/* … */);
const idbOpenRequest = unwrap(openPromise);