diff --git a/chrome/content/zotero/xpcom/storage.js b/chrome/content/zotero/xpcom/storage.js index 1f7f2e87f..d38f4d971 100644 --- a/chrome/content/zotero/xpcom/storage.js +++ b/chrome/content/zotero/xpcom/storage.js @@ -147,6 +147,7 @@ Zotero.Sync.Storage = new function () { } } return Q.allResolved(promises) + // Get library last-sync times .then(function () { var promises = []; for (var libraryID in libraryModes) { @@ -175,21 +176,29 @@ Zotero.Sync.Storage = new function () { return []; } + var libraryQueues = []; + + // Get the libraries we have sync times for promises.forEach(function (p) { p = p.valueOf(); - var libraryID = p[0].valueOf(); + let libraryID = p[0].valueOf(); + let lastSyncTime = p[1].valueOf(); if (p[1].isFulfilled()) { - librarySyncTimes[libraryID] = p[1].valueOf(); + librarySyncTimes[libraryID] = lastSyncTime; } else { - // TODO: error log of some sort - //librarySyncTimes[libraryID] = p[1].valueOf().exception; - Components.utils.reportError(p[1].valueOf().exception); + let e = lastSyncTime.exception; + Zotero.debug(e); + Components.utils.reportError(e); + // Pass rejected promise through + libraryQueues.push(Q.allResolved( + [libraryID, lastSyncTime] + )); } }); // Queue files to download and upload from each library - for (var libraryID in librarySyncTimes) { + for (let libraryID in librarySyncTimes) { var lastSyncTime = librarySyncTimes[libraryID]; libraryID = parseInt(libraryID); @@ -214,7 +223,7 @@ Zotero.Sync.Storage = new function () { if (downloadAll && !downloadForced && lastSyncTime) { var version = self.getStoredLastSyncTime( libraryModes[libraryID], libraryID - ); + ); if (version == lastSyncTime) { Zotero.debug("Last " + libraryModes[libraryID].name + " sync time hasn't changed for library " @@ -238,41 +247,57 @@ Zotero.Sync.Storage = new function () { } } - // TODO: change to start() for each library, with allResolved() - // for the whole set and all() for each library - return Zotero.Sync.Storage.QueueManager.start(); + // Start queues for each library + for (let libraryID in librarySyncTimes) { + libraryID = parseInt(libraryID); + libraryQueues.push(Q.allResolved( + [libraryID, Zotero.Sync.Storage.QueueManager.start(libraryID)] + )); + } + + // The promise is done when all libraries are done + return Q.allResolved(libraryQueues); }) .then(function (promises) { Zotero.debug('Queue manager is finished'); var changedLibraries = []; - var finalPromises = []; promises.forEach(function (promise) { - var result = promise.valueOf(); - if (promise.isFulfilled()) { - Zotero.debug("File " + result.type + " sync finished " - + "for library " + result.libraryID); - Zotero.debug(result); - if (result.localChanges) { - changedLibraries.push(result.libraryID); - } - finalPromises.push(Q.allResolved([ - result.libraryID, - libraryModes[result.libraryID].setLastSyncTime( - result.libraryID, - result.remoteChanges - ? false : librarySyncTimes[result.libraryID] - ) - ])); + // Discard first allResolved() promise + p = promise.valueOf(); + + var libraryID = p[0].valueOf(); + var libraryQueues = p[1].valueOf(); + + if (p[1].isFulfilled()) { + libraryQueues.forEach(function (queuePromise) { + let result = queuePromise.valueOf(); + if (queuePromise.isFulfilled()) { + Zotero.debug("File " + result.type + " sync finished " + + "for library " + libraryID); + if (result.localChanges) { + changedLibraries.push(libraryID); + } + finalPromises.push(Q.allResolved([ + libraryID, + libraryModes[libraryID].setLastSyncTime( + libraryID, + result.remoteChanges ? false : librarySyncTimes[libraryID] + ) + ])); + } + else { + Zotero.debug("File " + result.type + " sync failed " + + "for library " + libraryID); + finalPromises.push([libraryID, queuePromise]); + } + }); } else { - result = result.exception; - Zotero.debug("File " + result.type + " sync failed " - + "for library " + result.libraryID); - - finalPromises.push([result.libraryID, promise]); + Zotero.debug("File sync failed for library " + libraryID); + finalPromises.push([libraryID, libraryQueues]); } }); diff --git a/chrome/content/zotero/xpcom/storage/queueManager.js b/chrome/content/zotero/xpcom/storage/queueManager.js index ba8e7c437..4d584fdc3 100644 --- a/chrome/content/zotero/xpcom/storage/queueManager.js +++ b/chrome/content/zotero/xpcom/storage/queueManager.js @@ -31,12 +31,14 @@ Zotero.Sync.Storage.QueueManager = new function () { this.start = function (libraryID) { if (libraryID === 0 || libraryID) { var queues = this.getAll(libraryID); + var suffix = " for library " + libraryID; } else { var queues = this.getAll(); + var suffix = ""; } - Zotero.debug("Starting file sync queues"); + Zotero.debug("Starting file sync queues" + suffix); var promises = []; for each(var queue in queues) { @@ -48,13 +50,15 @@ Zotero.Sync.Storage.QueueManager = new function () { } if (!promises.length) { - Zotero.debug("No files to sync"); + Zotero.debug("No files to sync" + suffix); } return Q.allResolved(promises) .then(function (promises) { - Zotero.debug("All storage queues are finished"); + Zotero.debug("All storage queues are finished" + suffix); + promises.forEach(function (promise) { + // Check for conflicts to resolve if (promise.isFulfilled()) { var result = promise.valueOf(); if (result.conflicts.length) { @@ -67,7 +71,6 @@ Zotero.Sync.Storage.QueueManager = new function () { } } }); - return promises; }); }; @@ -125,6 +128,10 @@ Zotero.Sync.Storage.QueueManager = new function () { this.getAll = function (libraryID) { + if (typeof libraryID == 'string') { + throw new Error("libraryID must be a number or undefined"); + } + var queues = []; for each(var queue in _queues) { if (typeof libraryID == 'undefined' || queue.libraryID === libraryID) { diff --git a/chrome/content/zotero/xpcom/storage/webdav.js b/chrome/content/zotero/xpcom/storage/webdav.js index abaf105df..37901d328 100644 --- a/chrome/content/zotero/xpcom/storage/webdav.js +++ b/chrome/content/zotero/xpcom/storage/webdav.js @@ -55,8 +55,7 @@ Zotero.Sync.Storage.WebDAV = (function () { ) .then(function (req) { checkResponse(req); - }) - .then(function (req) { + var funcName = "Zotero.Sync.Storage.WebDAV.getStorageModificationTime()"; // mod_speling can return 300s for 404s with base name matches @@ -839,7 +838,6 @@ Zotero.Sync.Storage.WebDAV = (function () { if (!mdate) { Zotero.debug("Remote file not found for item " + Zotero.Items.getLibraryKeyHash(item)); - request.finish(); return false; } @@ -977,7 +975,7 @@ Zotero.Sync.Storage.WebDAV = (function () { return self._cacheCredentials(); }) .then(function () { - var lastSyncURI = this.rootURI; + var lastSyncURI = self.rootURI; lastSyncURI.spec += "lastsync"; return Zotero.HTTP.promise("GET", lastSyncURI, { debug: true, successCodes: [200, 404] }); @@ -1064,9 +1062,8 @@ Zotero.Sync.Storage.WebDAV = (function () { return Zotero.HTTP.promise("OPTIONS", this.rootURI) .then(function (req) { - return checkResponse(req); - }) - .then(function () { + checkResponse(req); + Zotero.debug("Credentials are cached"); _cachedCredentials = true; }) diff --git a/chrome/content/zotero/xpcom/sync.js b/chrome/content/zotero/xpcom/sync.js index fdb0adc5c..90a2c9955 100644 --- a/chrome/content/zotero/xpcom/sync.js +++ b/chrome/content/zotero/xpcom/sync.js @@ -567,10 +567,11 @@ Zotero.Sync.Runner = new function () { Zotero.Sync.Runner.stop(); } }) - .fail(function (e) { + .catch(function (e) { Zotero.debug("File sync failed", 1); Zotero.Sync.Runner.error(e); - }); + }) + .done(); }; Zotero.Sync.Server.sync({ @@ -620,7 +621,6 @@ Zotero.Sync.Runner = new function () { e = new Error(e); e.status = 'error'; } - Components.utils.reportError(e); Zotero.debug(e, 1); Zotero.Sync.Runner.setSyncIcon(e); throw (e); @@ -883,6 +883,7 @@ Zotero.Sync.Runner = new function () { } } if (!parsed.message) { + // TODO: include file name and line? parsed.message = e.message ? e.message : e; }