From bdec4b119fa116bc078a207b6030cb22cbed5435 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Mon, 22 Aug 2016 21:28:34 -0400 Subject: [PATCH] Fix error handling during local file import translation A failure during detect (which is normal during file import attempts) would cause later translator detection to fail. --- .../zotero/xpcom/translation/translate.js | 80 ++++++------------- .../xpcom/translation/translate_firefox.js | 10 +-- .../zotero/xpcom/translation/translators.js | 5 +- test/tests/data/mods.xml | 10 +++ test/tests/fileInterfaceTest.js | 13 +++ 5 files changed, 55 insertions(+), 63 deletions(-) create mode 100644 test/tests/data/mods.xml diff --git a/chrome/content/zotero/xpcom/translation/translate.js b/chrome/content/zotero/xpcom/translation/translate.js index ec4758fb8..2cb2b8408 100644 --- a/chrome/content/zotero/xpcom/translation/translate.js +++ b/chrome/content/zotero/xpcom/translation/translate.js @@ -1595,9 +1595,15 @@ Zotero.Translate.Base.prototype = { return; } - var me = this; - this._loadTranslator(this._potentialTranslators[0]). - then(function() { me._detectTranslatorLoaded() }); + let lab = this._potentialTranslators[0].label; + this._loadTranslator(this._potentialTranslators[0]) + .bind(this) + .then(function() { + return this._detectTranslatorLoaded(); + }) + .catch(function (e) { + this.complete(false, e); + }); }, /** @@ -2146,64 +2152,31 @@ Zotero.Translate.Import.prototype.getTranslators = function() { /** * Overload {@link Zotero.Translate.Base#_loadTranslator} to prepare translator IO */ -Zotero.Translate.Import.prototype._loadTranslator = function(translator, callback) { - // call super - var me = this; - return Zotero.Translate.Base.prototype._loadTranslator.call(this, translator). - then(function() { - me._loadTranslatorPrepareIO(translator, callback); - }); +Zotero.Translate.Import.prototype._loadTranslator = function(translator) { + return Zotero.Translate.Base.prototype._loadTranslator.call(this, translator) + .then(function() { + return this._loadTranslatorPrepareIO(translator); + }.bind(this)); } /** * Prepare translator IO */ -Zotero.Translate.Import.prototype._loadTranslatorPrepareIO = function(translator, callback) { +Zotero.Translate.Import.prototype._loadTranslatorPrepareIO = Zotero.Promise.method(function (translator) { var configOptions = this._translatorInfo.configOptions; var dataMode = configOptions ? configOptions["dataMode"] : ""; - var me = this; - var initCallback = function(status, err) { - if(!status) { - me.complete(false, err); - } else { - me._sandboxManager.importObject(me._io); - if(callback) callback(); - } - }; - - var err = false; if(!this._io) { if(Zotero.Translate.IO.Read && this.location && this.location instanceof Components.interfaces.nsIFile) { - try { - this._io = new Zotero.Translate.IO.Read(this.location, this._sandboxManager); - } catch(e) { - err = e; - } + this._io = new Zotero.Translate.IO.Read(this.location, this._sandboxManager); } else { - try { - this._io = new Zotero.Translate.IO.String(this._string, this.path ? this.path : "", this._sandboxManager); - } catch(e) { - err = e; - } - } - - if(err) { - this.complete(false, err); - return; + this._io = new Zotero.Translate.IO.String(this._string, this.path ? this.path : "", this._sandboxManager); } } - try { - this._io.init(dataMode, initCallback); - } catch(e) { - err = e; - } - if(err) { - this.complete(false, err); - return; - } -} + this._io.init(dataMode); + this._sandboxManager.importObject(this._io); +}); /** * Prepare translation @@ -2585,7 +2558,7 @@ Zotero.Translate.IO.String.prototype = { "getXML":"r" }, - "_initRDF":function(callback) { + "_initRDF": function () { Zotero.debug("Translate: Initializing RDF data store"); this._dataStore = new Zotero.RDF.AJAW.IndexedFormula(); this.RDF = new Zotero.Translate.IO._RDFSandbox(this._dataStore); @@ -2600,7 +2573,6 @@ Zotero.Translate.IO.String.prototype = { var parser = new Zotero.RDF.AJAW.RDFParser(this._dataStore); parser.parse(xml, this._uri); } - callback(true); }, "setCharacterSet":function(charset) {}, @@ -2666,20 +2638,18 @@ Zotero.Translate.IO.String.prototype = { return (Zotero.isFx && !Zotero.isBookmarklet ? this._sandboxManager.wrap(xml) : xml); }, - "init":function(newMode, callback) { + init: function (newMode) { this.bytesRead = 0; this._noCR = undefined; this._mode = newMode; if(newMode === "xml/e4x") { - throw "E4X is not supported"; + throw new Error("E4X is not supported"); } else if(newMode && (Zotero.Translate.IO.rdfDataModes.indexOf(newMode) !== -1 || newMode.substr(0, 3) === "xml/dom") && this._xmlInvalid) { - throw "XML known invalid"; + throw new Error("XML known invalid"); } else if(Zotero.Translate.IO.rdfDataModes.indexOf(this._mode) !== -1) { - this._initRDF(callback); - } else { - callback(true); + this._initRDF(); } }, diff --git a/chrome/content/zotero/xpcom/translation/translate_firefox.js b/chrome/content/zotero/xpcom/translation/translate_firefox.js index 9dec02933..a803b9ee2 100644 --- a/chrome/content/zotero/xpcom/translation/translate_firefox.js +++ b/chrome/content/zotero/xpcom/translation/translate_firefox.js @@ -845,7 +845,7 @@ Zotero.Translate.IO.Read.prototype = { this.RDF = new Zotero.Translate.IO._RDFSandbox(this._dataStore); } catch(e) { this.close(); - throw "Translate: No RDF found"; + throw new Error("Translate: No RDF found"); } }, @@ -893,7 +893,7 @@ Zotero.Translate.IO.Read.prototype = { return (Zotero.isFx ? this._sandboxManager.wrap(xml) : xml); }, - "init":function(newMode, callback) { + init: function (newMode) { if(Zotero.Translate.IO.maintainedInstances.indexOf(this) === -1) { Zotero.Translate.IO.maintainedInstances.push(this); } @@ -901,12 +901,10 @@ Zotero.Translate.IO.Read.prototype = { this._mode = newMode; if(newMode === "xml/e4x") { - throw "E4X is not supported"; + throw new Error("E4X is not supported"); } else if(Zotero.Translate.IO.rdfDataModes.indexOf(this._mode) !== -1 && !this.RDF) { this._initRDF(); } - - callback(true); }, "close":function() { @@ -988,7 +986,7 @@ Zotero.Translate.IO.Write.prototype = { this._writtenToStream = true; }, - "init":function(newMode, charset, callback) { + init: function (newMode, charset) { this._mode = newMode; if(Zotero.Translate.IO.rdfDataModes.indexOf(this._mode) !== -1) { this._initRDF(); diff --git a/chrome/content/zotero/xpcom/translation/translators.js b/chrome/content/zotero/xpcom/translation/translators.js index 40fb1bae6..174fd6d65 100644 --- a/chrome/content/zotero/xpcom/translation/translators.js +++ b/chrome/content/zotero/xpcom/translation/translators.js @@ -342,8 +342,9 @@ Zotero.Translators = new function() { * Gets import translators for a specific location * @param {String} location The location for which to look for translators * @param {Function} [callback] An optional callback to be executed when translators have been - * retrieved. If no callback is specified, translators are - * returned. + * retrieved + * @return {Promise} - An array of translators if no callback is specified; + * otherwise true */ this.getImportTranslatorsForLocation = function(location, callback) { return Zotero.Translators.getAllForType("import").then(function(allTranslators) { diff --git a/test/tests/data/mods.xml b/test/tests/data/mods.xml new file mode 100644 index 000000000..f2329c192 --- /dev/null +++ b/test/tests/data/mods.xml @@ -0,0 +1,10 @@ + + + + + Test + + text + journalArticle + + \ No newline at end of file diff --git a/test/tests/fileInterfaceTest.js b/test/tests/fileInterfaceTest.js index 1e505e7f0..13d119dee 100644 --- a/test/tests/fileInterfaceTest.js +++ b/test/tests/fileInterfaceTest.js @@ -73,4 +73,17 @@ describe("Zotero_File_Interface", function() { assert.lengthOf(matches, 1); assert.propertyVal(matches[0], 'id', attachment.id); }); + + it('should import a MODS file', function* () { + var modsFile = OS.Path.join(getTestDataDirectory().path, "mods.xml"); + + var promise = waitForItemEvent('add'); + yield win.Zotero_File_Interface.importFile(Zotero.File.pathToFile(modsFile)); + var ids = yield promise; + assert.lengthOf(ids, 1); + + var item = Zotero.Items.get(ids[0]); + assert.equal(item.itemTypeID, Zotero.ItemTypes.getID('journalArticle')); + assert.equal(item.getField('title'), "Test"); + }); }); \ No newline at end of file