commit 013dc958b303c717ee4bbb0d5861d254fd27fb4b
parent 5d16352f5733f377e4e01ecb8f8d0f96b9ccab4a
Author: Dan Stillman <dstillman@zotero.org>
Date: Wed, 31 May 2017 00:07:24 -0400
Restore cleaner error and item-selection button for note-too-long error
Diffstat:
2 files changed, 100 insertions(+), 92 deletions(-)
diff --git a/chrome/content/zotero/xpcom/sync.js b/chrome/content/zotero/xpcom/sync.js
@@ -286,40 +286,6 @@ Zotero.Sync.Server = new function () {
}, 1);
break;
- case 'NOTE_TOO_LONG':
- if (!Zotero.Sync.Runner.background) {
- let libraryKey = xmlhttp.responseXML.firstChild.getElementsByTagName('item');
- if (libraryKey.length) {
- let [libraryID, key] = libraryKey[0].textContent.split('/');
- if (Zotero.Libraries.getType(libraryID) == 'user') {
- libraryID = null;
- }
- let item = Zotero.Items.getByLibraryAndKey(libraryID, key);
- if (item) {
- let msg = xmlhttp.responseXML.firstChild.getElementsByTagName('error')[0].textContent;
- let e = new Zotero.Error(
- msg,
- 0,
- {
- dialogButtonText: Zotero.getString('pane.items.showItemInLibrary'),
- dialogButtonCallback: function () {
- var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
- var win = wm.getMostRecentWindow("navigator:browser");
- win.ZoteroPane.selectItem(item.id);
- }
- }
- );
- _error(e);
- }
- else {
- let msg = "Long note " + libraryKey[0].textContent + " not found!";
- Zotero.debug(msg, 1);
- Components.utils.reportError(msg);
- }
- }
- }
- break;
// We can't reproduce it, but we can fix it
case 'WRONG_LIBRARY_TAG_ITEM':
diff --git a/chrome/content/zotero/xpcom/sync/syncEngine.js b/chrome/content/zotero/xpcom/sync/syncEngine.js
@@ -1145,66 +1145,15 @@ Zotero.Sync.Data.Engine.prototype._uploadObjects = Zotero.Promise.coroutine(func
if (data) {
e.data = data;
}
- Zotero.logError("Error for " + objectType + " " + jsonBatch[index].key + " in "
+ Zotero.logError(`Error ${code} for ${objectType} ${jsonBatch[index].key} in `
+ this.library.name + ":\n\n" + e);
- // If an item's dependency is missing remotely and it isn't in the queue (which
- // shouldn't happen), mark it as unsynced
- if (e.code == 400 || e.code == 409) {
- if (data) {
- if (objectType == 'collection' && e.code == 409) {
- if (data.collection) {
- let collection = Zotero.Collections.getByLibraryAndKey(this.libraryID, data.collection);
- if (!collection) {
- throw new Error(`Collection ${this.libraryID}/${jsonBatch[index].key} `
- + `references parent collection ${data.collection}, which doesn't exist`);
- }
- Zotero.logError(`Marking collection ${data.collection} as unsynced`);
- yield Zotero.Sync.Data.Local.markObjectAsUnsynced(collection);
- }
- }
- else if (objectType == 'item') {
- if (data.collection) {
- let collection = Zotero.Collections.getByLibraryAndKey(this.libraryID, data.collection);
- if (!collection) {
- throw new Error(`Item ${this.libraryID}/${jsonBatch[index].key} `
- + `references collection ${data.collection}, which doesn't exist`);
- }
- Zotero.logError(`Marking collection ${data.collection} as unsynced`);
- yield Zotero.Sync.Data.Local.markObjectAsUnsynced(collection);
- }
- else if (data.parentItem) {
- let parentItem = Zotero.Items.getByLibraryAndKey(this.libraryID, data.parentItem);
- if (!parentItem) {
- throw new Error(`Item ${this.libraryID}/${jsonBatch[index].key} references parent `
- + `item ${data.parentItem}, which doesn't exist`);
- }
-
- let id = parentItem.id;
- // If parent item isn't already in queue, mark it as unsynced and add it
- if (!queue.find(o => o.id == id) && !batch.find(o => o.id == id)) {
- yield Zotero.Sync.Data.Local.markObjectAsUnsynced(parentItem);
- Zotero.logError(`Adding parent item ${data.parentItem} to upload queue`);
- queue.push({
- id,
- json: null,
- tries: 0,
- failed: false
- });
- // Pretend that we were successful so syncing continues
- numSuccessful++;
- continue;
- }
- }
- }
- }
- }
-
- // This shouldn't happen, because the upload request includes a library version and should
- // prevent an outdated upload before the object version is checked. If it does, we need to
- // do a full sync. This error is checked in handleUploadError().
- if (e.code == 404 || e.code == 412) {
- throw e;
+ let keepGoing = yield this._checkObjectUploadError(
+ objectType, jsonBatch[index].key, e, queue
+ );
+ if (keepGoing) {
+ numSuccessful++;
+ continue;
}
if (this.onError) {
@@ -1654,6 +1603,99 @@ Zotero.Sync.Data.Engine.prototype._handleUploadError = Zotero.Promise.coroutine(
throw e;
});
+
+Zotero.Sync.Data.Engine.prototype._checkObjectUploadError = Zotero.Promise.coroutine(function* (objectType, key, e) {
+ var { code, data, message } = e;
+
+ // If an item's dependency is missing remotely and it isn't in the queue (which
+ // shouldn't happen), mark it as unsynced
+ if (code == 400 || code == 409) {
+ if (data) {
+ if (objectType == 'collection' && code == 409) {
+ if (data.collection) {
+ let collection = Zotero.Collections.getByLibraryAndKey(this.libraryID, data.collection);
+ if (!collection) {
+ throw new Error(`Collection ${this.libraryID}/${key} `
+ + `references parent collection ${data.collection}, which doesn't exist`);
+ }
+ Zotero.logError(`Marking collection ${data.collection} as unsynced`);
+ yield Zotero.Sync.Data.Local.markObjectAsUnsynced(collection);
+ }
+ }
+ else if (objectType == 'item') {
+ if (data.collection) {
+ let collection = Zotero.Collections.getByLibraryAndKey(this.libraryID, data.collection);
+ if (!collection) {
+ throw new Error(`Item ${this.libraryID}/${key} `
+ + `references collection ${data.collection}, which doesn't exist`);
+ }
+ Zotero.logError(`Marking collection ${data.collection} as unsynced`);
+ yield Zotero.Sync.Data.Local.markObjectAsUnsynced(collection);
+ }
+ else if (data.parentItem) {
+ let parentItem = Zotero.Items.getByLibraryAndKey(this.libraryID, data.parentItem);
+ if (!parentItem) {
+ throw new Error(`Item ${this.libraryID}/${key} references parent `
+ + `item ${data.parentItem}, which doesn't exist`);
+ }
+
+ let id = parentItem.id;
+ // If parent item isn't already in queue, mark it as unsynced and add it
+ if (!queue.find(o => o.id == id) && !batch.find(o => o.id == id)) {
+ yield Zotero.Sync.Data.Local.markObjectAsUnsynced(parentItem);
+ Zotero.logError(`Adding parent item ${data.parentItem} to upload queue`);
+ queue.push({
+ id,
+ json: null,
+ tries: 0,
+ failed: false
+ });
+ // Pretend that we were successful so syncing continues
+ return true;
+ }
+ }
+ }
+ }
+ }
+ // This shouldn't happen, because the upload request includes a library version and should
+ // prevent an outdated upload before the object version is checked. If it does, we need to
+ // do a full sync. This error is checked in handleUploadError().
+ else if (code == 404 || code == 412) {
+ throw e;
+ }
+ else if (code == 413) {
+ // Note too long
+ if (objectType == 'item') {
+ let item = Zotero.Items.getByLibraryAndKey(this.libraryID, key);
+ if (item) {
+ // Throw an error that adds a button for selecting the item to the sync error dialog
+ if (message.includes('<img src="data:image')) {
+ // TODO: Localize
+ message = "Notes with embedded images cannot currently be synced to "
+ + `${ZOTERO_CONFIG.DOMAIN_NAME}.`
+ }
+
+ e = new Zotero.Error(
+ message,
+ 0,
+ {
+ dialogButtonText: Zotero.getString('pane.items.showItemInLibrary'),
+ dialogButtonCallback: () => {
+ var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Components.interfaces.nsIWindowMediator);
+ var win = wm.getMostRecentWindow("navigator:browser");
+ win.ZoteroPane.selectItem(item.id);
+ }
+ }
+ );
+ }
+ throw e;
+ }
+ }
+ return false;
+});
+
+
Zotero.Sync.Data.Engine.prototype._failedCheck = function () {
if (this.stopOnError && this.failed) {
Zotero.logError("Stopping on error");