www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

commit cebf2a31259f57e719756c7d8231de8e49520037
parent 0c5eacbd0fe9dc3acd25a4fd49707a6396f4fd4f
Author: Dan Stillman <dstillman@zotero.org>
Date:   Mon, 28 Mar 2016 17:47:25 -0400

Throw an error from queryAsync() if onRow throws an error

If onRow throws StopIteration, the query will stop gracefully.

Diffstat:
Mchrome/content/zotero/xpcom/db.js | 15+++++++++++----
Mtest/tests/dbTest.js | 38++++++++++++++++++++++++++++++++++++++
2 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/chrome/content/zotero/xpcom/db.js b/chrome/content/zotero/xpcom/db.js @@ -613,6 +613,7 @@ Zotero.DBConnection.prototype.queryAsync = Zotero.Promise.coroutine(function* (s if (Zotero.Debug.enabled) { this.logQuery(sql, params, options); } + var failed = false; if (options && options.onRow) { // Errors in onRow don't stop the query unless StopIteration is thrown onRow = function (row) { @@ -620,12 +621,15 @@ Zotero.DBConnection.prototype.queryAsync = Zotero.Promise.coroutine(function* (s options.onRow(row); } catch (e) { + // If the onRow throws a StopIteration, stop gracefully if (e instanceof StopIteration) { - Zotero.debug("Query cancelled"); - throw e; + Zotero.debug("Query cancelled", 3); + } + // Otherwise, mark the promise as rejected, which Sqlite.jsm doesn't do + // on a StopIteration by default + else { + failed = e; } - Zotero.debug(e, 1); - Components.utils.reportError(e); throw StopIteration; } } @@ -637,6 +641,9 @@ Zotero.DBConnection.prototype.queryAsync = Zotero.Promise.coroutine(function* (s else { rows = yield conn.executeCached(sql, params, onRow); } + if (failed) { + throw failed; + } // Parse out the SQL command being used let op = sql.match(/^[^a-z]*[^ ]+/i); if (op) { diff --git a/test/tests/dbTest.js b/test/tests/dbTest.js @@ -131,6 +131,44 @@ describe("Zotero.DB", function() { assert.equal(rows[0].a, 1); assert.equal(rows[1].a, 2); }) + + it("should throw an error if onRow throws an error", function* () { + var i = 0; + var e = Zotero.DB.queryAsync( + "SELECT * FROM " + tmpTable, + false, + { + onRow: function (row) { + if (i > 0) { + throw new Error("Failed"); + } + i++; + } + } + ); + e = yield getPromiseError(e) + assert.ok(e); + assert.equal(e.message, "Failed"); + }); + + it("should stop gracefully if onRow throws a StopIteration", function* () { + var i = 0; + var rows = []; + yield Zotero.DB.queryAsync( + "SELECT * FROM " + tmpTable, + false, + { + onRow: function (row) { + if (i > 0) { + throw StopIteration; + } + rows.push(row.getResultByIndex(0)); + i++; + } + } + ); + assert.lengthOf(rows, 1); + }); })