'Detecting/preventing Firefox IndexedDB InvalidStateError caused by private browsing
I'm integrating a javascript library that uses IndexedDB, but it fails "ungraciously" when Firefox is in private browsing/window mode. The library returns out a 500 Internal Error and meanwhile Firefox spits out an InvalidStateError to console.
What I'd like to do is add a check before I instantiate this library, and not use the library at all if IndexedDB is not available. i.e. some type of try/catch test. From what I've seen, Firefox appears to spit out the console error even if the offending code is inside a try/catch (but maybe there's still a way..).
I don't actually have an interest whether the user is in a private window session or not, but that seems to be the only time when Firefox causes this InvalidStateError.
Solution 1:[1]
You have handle the errors in the onerror function.
This won't tell you for definite that the use is "In Private", but will tell you you can't use indexedDB - from which you could interpolate if you needed to - ie if its FireFox and this throws and error then chances are they are In Private - until the guys at Mozilla fix it.
var db = window.indexedDB.open('test');
db.onerror = function()
{
console.log("Can't use indexedDB")
}
This still kicks out the InvalidStateError to the console, but the js can handle the consequences.
Solution 2:[2]
I used indexedDB to check is user in private browsing mode. The is InvalidStateError appears on window.onerror and logged via tracking system. It looks like opening happened in different thread. I've found only this primitive solution: set global handler window.onerror, to hide this error.
// Get old handler (maybe undefined)
const oldHandler = window.onerror;
// Empty handler
const noop = () => 1;
window.onerror = noop;
const returnOldHandler = () => setTimeout(() => {
// The ugly thing: we some external code could place own onerror handler
// between our code evaluation.
// For this case we should check is it changed.
if (window.onerror === noop) {
window.onerror = oldHandler;
}
}, 0);
try {
db = window.indexedDB.open('test');
// Return global handler when DB opens.
// It can create some errors due async process.
db.onerror = returnOldHandler;
db.onsuccess = returnOldHandler;
} catch(e) {
// never evaluate
}
Solution 3:[3]
This is intentional due to privacy reason:
Note: In private browsing mode, most data storage is not supported. Local storage data and cookies are still stored, but they are ephemeral — the data is deleted when you close the last private browsing window.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Morvael |
| Solution 2 | Dmitry Manannikov |
| Solution 3 | 4ntoine |
