(#3415) - open idb transactions safely
diff --git a/lib/adapters/idb/idb-bulk-docs.js b/lib/adapters/idb/idb-bulk-docs.js index becaeda..7dcccf3 100644 --- a/lib/adapters/idb/idb-bulk-docs.js +++ b/lib/adapters/idb/idb-bulk-docs.js
@@ -16,6 +16,7 @@ var decodeMetadata = idbUtils.decodeMetadata; var encodeMetadata = idbUtils.encodeMetadata; var idbError = idbUtils.idbError; +var openTransactionSafely = idbUtils.openTransactionSafely; function idbBulkDocs(req, opts, api, idb, Changes, callback) { var docInfos = req.docs; @@ -60,7 +61,11 @@ ATTACH_STORE, META_STORE, LOCAL_STORE, ATTACH_AND_SEQ_STORE ]; - txn = idb.transaction(stores, 'readwrite'); + var txnResult = openTransactionSafely(idb, stores, 'readwrite'); + if (txnResult.error) { + return callback(txnResult.error); + } + txn = txnResult.txn; txn.onerror = idbError(callback); txn.ontimeout = idbError(callback); txn.oncomplete = complete;
diff --git a/lib/adapters/idb/idb-utils.js b/lib/adapters/idb/idb-utils.js index d4a3827..4a80d75 100644 --- a/lib/adapters/idb/idb-utils.js +++ b/lib/adapters/idb/idb-utils.js
@@ -229,3 +229,15 @@ }; }); }; + +exports.openTransactionSafely = function (idb, stores, mode) { + try { + return { + txn: idb.transaction(stores, mode) + }; + } catch (err) { + return { + error: err + }; + } +}; \ No newline at end of file
diff --git a/lib/adapters/idb/idb.js b/lib/adapters/idb/idb.js index 7169432..4cdae49 100644 --- a/lib/adapters/idb/idb.js +++ b/lib/adapters/idb/idb.js
@@ -27,6 +27,7 @@ var postProcessAttachments = idbUtils.postProcessAttachments; var readBlobData = idbUtils.readBlobData; var taskQueue = idbUtils.taskQueue; +var openTransactionSafely = idbUtils.openTransactionSafely; var cachedDBs = {}; var blobSupportPromise; @@ -296,8 +297,12 @@ if (opts.ctx) { txn = opts.ctx; } else { - txn = - idb.transaction([DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly'); + var txnResult = openTransactionSafely(idb, + [DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly'); + if (txnResult.error) { + return callback(txnResult.error); + } + txn = txnResult.txn; } function finish() { @@ -344,8 +349,12 @@ if (opts.ctx) { txn = opts.ctx; } else { - txn = - idb.transaction([DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly'); + var txnResult = openTransactionSafely(idb, + [DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly'); + if (txnResult.error) { + return callback(txnResult.error); + } + txn = txnResult.txn; } var digest = attachment.digest; var type = attachment.content_type; @@ -412,7 +421,11 @@ if (opts.attachments) { stores.push(ATTACH_STORE); } - var transaction = idb.transaction(stores, 'readonly'); + var txnResult = openTransactionSafely(idb, stores, 'readonly'); + if (txnResult.error) { + return callback(txnResult.error); + } + var transaction = txnResult.txn; function onResultsReady() { callback(null, { @@ -500,7 +513,11 @@ } var count; - var txn = idb.transaction([DOC_STORE], 'readonly'); + var txnResult = openTransactionSafely(idb, [DOC_STORE], 'readonly'); + if (txnResult.error) { + return callback(txnResult.error); + } + var txn = txnResult.txn; var index = txn.objectStore(DOC_STORE).index('deletedOrLocal'); index.count(IDBKeyRange.only("0")).onsuccess = function (e) { count = e.target.result; @@ -542,7 +559,11 @@ return callback(error); } var updateSeq = 0; - var txn = idb.transaction([BY_SEQ_STORE], 'readonly'); + var txnResult = openTransactionSafely(idb, [BY_SEQ_STORE], 'readonly'); + if (txnResult.error) { + return callback(txnResult.error); + } + var txn = txnResult.txn; txn.objectStore(BY_SEQ_STORE).openCursor(null, "prev").onsuccess = function (event) { var cursor = event.target.result; @@ -689,7 +710,11 @@ if (opts.attachments) { objectStores.push(ATTACH_STORE); } - txn = idb.transaction(objectStores, 'readonly'); + var txnResult = openTransactionSafely(idb, objectStores, 'readonly'); + if (txnResult.error) { + return opts.complete(txnResult.error); + } + txn = txnResult.txn; txn.onerror = idbError(opts.complete); txn.oncomplete = onTxnComplete; @@ -745,7 +770,11 @@ }; api._getRevisionTree = function (docId, callback) { - var txn = idb.transaction([DOC_STORE], 'readonly'); + var txnResult = openTransactionSafely(idb, [DOC_STORE], 'readonly'); + if (txnResult.error) { + return callback(txnResult.error); + } + var txn = txnResult.txn; var req = txn.objectStore(DOC_STORE).get(docId); req.onsuccess = function (event) { var doc = decodeMetadata(event.target.result); @@ -761,12 +790,17 @@ // which are listed in revs and sets this document // revision to to rev_tree api._doCompaction = function (docId, revs, callback) { - var txn = idb.transaction([ + var stores = [ DOC_STORE, BY_SEQ_STORE, ATTACH_STORE, ATTACH_AND_SEQ_STORE - ], 'readwrite'); + ]; + var txnResult = openTransactionSafely(idb, stores, 'readwrite'); + if (txnResult.error) { + return callback(txnResult.error); + } + var txn = txnResult.txn; var docStore = txn.objectStore(DOC_STORE); @@ -793,7 +827,11 @@ api._getLocal = function (id, callback) { - var tx = idb.transaction([LOCAL_STORE], 'readonly'); + var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readonly'); + if (txnResult.error) { + return callback(txnResult.error); + } + var tx = txnResult.txn; var req = tx.objectStore(LOCAL_STORE).get(id); req.onerror = idbError(callback); @@ -825,7 +863,11 @@ var tx = opts.ctx; var ret; if (!tx) { - tx = idb.transaction([LOCAL_STORE], 'readwrite'); + var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readwrite'); + if (txnResult.error) { + return callback(txnResult.error); + } + tx = txnResult.txn; tx.onerror = idbError(callback); tx.oncomplete = function () { if (ret) { @@ -870,7 +912,11 @@ }; api._removeLocal = function (doc, callback) { - var tx = idb.transaction([LOCAL_STORE], 'readwrite'); + var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readwrite'); + if (txnResult.error) { + return callback(txnResult.error); + } + var tx = txnResult.txn; var ret; tx.oncomplete = function () { if (ret) {