Bug 1458640 - Prevent any fatal indexedDB errors from crashing section

This commit is contained in:
k88hudson 2018-05-02 16:13:38 -04:00
Родитель 4cfb63564d
Коммит 922de73f13
3 изменённых файлов: 42 добавлений и 6 удалений

Просмотреть файл

@ -91,7 +91,7 @@ class _ASRouter {
this.initialized = true;
this._storage = storage;
const blockList = await this._storage.get("blockList");
const blockList = await this._storage.get("blockList") || [];
this.setState({blockList});
}

Просмотреть файл

@ -16,7 +16,7 @@ this.ActivityStreamStorage = class ActivityStreamStorage {
}
get db() {
return this._db || (this._db = this._openDatabase());
return this._db || (this._db = this.createOrOpenDb());
}
/**
@ -65,6 +65,26 @@ this.ActivityStreamStorage = class ActivityStreamStorage {
});
}
/**
* createOrOpenDb - Open a db (with this.dbName) if it exists.
* If it does not exist, create it.
* If an error occurs, deleted the db and attempt to
* re-create it.
* @returns Promise that resolves with a db instance
*/
async createOrOpenDb() {
try {
const db = await this._openDatabase();
return db;
} catch (e) {
if (this.telemetry) {
this.telemetry.handleUndesiredEvent({data: {event: "INDEXEDDB_OPEN_FAILED"}});
}
await IndexedDB.deleteDatabase(this.dbName);
return this._openDatabase();
}
}
async _requestWrapper(request) {
let result = null;
try {

Просмотреть файл

@ -9,7 +9,10 @@ describe("ActivityStreamStorage", () => {
let storage;
beforeEach(() => {
sandbox = sinon.sandbox.create();
indexedDB = {open: sandbox.stub().resolves({})};
indexedDB = {
open: sandbox.stub().resolves({}),
deleteDatabase: sandbox.stub().resolves()
};
overrider.set({IndexedDB: indexedDB});
storage = new ActivityStreamStorage({
storeNames: ["storage_test"],
@ -19,12 +22,25 @@ describe("ActivityStreamStorage", () => {
afterEach(() => {
sandbox.restore();
});
it("should not throw an error when accessing db", async () => {
assert.ok(storage.db);
});
it("should throw if required arguments not provided", () => {
assert.throws(() => new ActivityStreamStorage({telemetry: true}));
});
describe(".db", () => {
it("should not throw an error when accessing db", async () => {
assert.ok(storage.db);
});
it("should delete and recreate the db if opening db fails", async () => {
const newDb = {};
indexedDB.open.onFirstCall().rejects(new Error("fake error"));
indexedDB.open.onSecondCall().resolves(newDb);
const db = await storage.db;
assert.calledOnce(indexedDB.deleteDatabase);
assert.calledTwice(indexedDB.open);
assert.equal(db, newDb);
});
});
describe("#getDbTable", () => {
let testStorage;
let storeStub;