Skip to content

Commit b622ebc

Browse files
eight04Mottie
authored andcommitted
Add: store the reason why db failed (#550)
* Add: store the reason why db failed * Add: add a warning * fixup! Add: add a warning
1 parent deeba1b commit b622ebc

File tree

1 file changed

+56
-30
lines changed

1 file changed

+56
-30
lines changed

background/db.js

+56-30
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* global tryCatch chromeLocal ignoreChromeError */
1+
/* global chromeLocal ignoreChromeError workerUtil */
22
/* exported db */
33
/*
44
Initialize a database. There are some problems using IndexedDB in Firefox:
@@ -18,52 +18,78 @@ const db = (() => {
1818
};
1919

2020
function prepare() {
21+
return shouldUseIndexedDB().then(
22+
ok => {
23+
if (ok) {
24+
useIndexedDB();
25+
} else {
26+
useChromeStorage();
27+
}
28+
},
29+
err => {
30+
useChromeStorage(err);
31+
}
32+
);
33+
}
34+
35+
function shouldUseIndexedDB() {
2136
// we use chrome.storage.local fallback if IndexedDB doesn't save data,
2237
// which, once detected on the first run, is remembered in chrome.storage.local
2338
// for reliablility and in localStorage for fast synchronous access
2439
// (FF may block localStorage depending on its privacy options)
25-
40+
if (typeof indexedDB === 'undefined') {
41+
return Promise.reject(new Error('indexedDB is undefined'));
42+
}
2643
// test localStorage
2744
const fallbackSet = localStorage.dbInChromeStorage;
28-
if (fallbackSet === 'true' || !tryCatch(() => indexedDB)) {
29-
useChromeStorage();
30-
return Promise.resolve();
45+
if (fallbackSet === 'true') {
46+
return Promise.resolve(false);
3147
}
3248
if (fallbackSet === 'false') {
33-
useIndexedDB();
34-
return Promise.resolve();
49+
return Promise.resolve(true);
3550
}
3651
// test storage.local
3752
return chromeLocal.get('dbInChromeStorage')
38-
.then(data =>
39-
data && data.dbInChromeStorage && Promise.reject())
40-
.then(() =>
41-
tryCatch(dbExecIndexedDB, 'getAllKeys', IDBKeyRange.lowerBound(1), 1) ||
42-
Promise.reject())
43-
.then(({target}) => (
44-
(target.result || [])[0] ?
45-
Promise.reject('ok') :
46-
dbExecIndexedDB('put', {id: -1})))
47-
.then(() =>
48-
dbExecIndexedDB('get', -1))
49-
.then(({target}) => (
50-
(target.result || {}).id === -1 ?
51-
dbExecIndexedDB('delete', -1) :
52-
Promise.reject()))
53-
.then(() =>
54-
Promise.reject('ok'))
55-
.catch(result => {
56-
if (result === 'ok') {
57-
useIndexedDB();
58-
} else {
59-
useChromeStorage();
53+
.then(data => {
54+
if (data && data.dbInChromeStorage) {
55+
return false;
6056
}
57+
return testDBSize()
58+
.then(ok => ok || testDBMutation());
6159
});
6260
}
6361

64-
function useChromeStorage() {
62+
function testDBSize() {
63+
return dbExecIndexedDB('getAllKeys', IDBKeyRange.lowerBound(1), 1)
64+
.then(event => (
65+
event.target.result &&
66+
event.target.result.length &&
67+
event.target.result[0]
68+
));
69+
}
70+
71+
function testDBMutation() {
72+
return dbExecIndexedDB('put', {id: -1})
73+
.then(() => dbExecIndexedDB('get', -1))
74+
.then(event => {
75+
if (!event.target.result) {
76+
throw new Error('failed to get previously put item');
77+
}
78+
if (event.target.result.id !== -1) {
79+
throw new Error('item id is wrong');
80+
}
81+
return dbExecIndexedDB('delete', -1);
82+
})
83+
.then(() => true);
84+
}
85+
86+
function useChromeStorage(err) {
6587
exec = dbExecChromeStorage;
6688
chromeLocal.set({dbInChromeStorage: true}, ignoreChromeError);
89+
if (err) {
90+
chromeLocal.setValue('dbInChromeStorageReason', workerUtil.cloneError(err));
91+
console.warn('Failed to access indexedDB. Switched to storage API.', err);
92+
}
6793
localStorage.dbInChromeStorage = 'true';
6894
}
6995

0 commit comments

Comments
 (0)