diff --git a/.babelrc b/.babelrc index 094c0592..08b4065a 100644 --- a/.babelrc +++ b/.babelrc @@ -10,5 +10,10 @@ "modules": false, "useBuiltIns": true }] + ], + "plugins": [ + ["babel-plugin-transform-builtin-extend", { + "globals": ["Error"] + }] ] } diff --git a/package-lock.json b/package-lock.json index 8df6b2dd..1bcdb061 100644 --- a/package-lock.json +++ b/package-lock.json @@ -228,14 +228,12 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" }, "anymatch": { "version": "2.0.0", @@ -471,7 +469,6 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, "requires": { "chalk": "1.1.3", "esutils": "2.0.2", @@ -681,7 +678,6 @@ "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true, "requires": { "babel-runtime": "6.26.0" } @@ -724,6 +720,15 @@ "babel-runtime": "6.26.0" } }, + "babel-plugin-transform-builtin-extend": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-builtin-extend/-/babel-plugin-transform-builtin-extend-1.1.2.tgz", + "integrity": "sha1-Xpb+z1i4+h7XTvytiEdbKvPJEW4=", + "requires": { + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, "babel-plugin-transform-es2015-arrow-functions": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", @@ -1071,7 +1076,6 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", - "dev": true, "requires": { "babel-runtime": "6.26.0", "babel-traverse": "6.26.0", @@ -1084,7 +1088,6 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "dev": true, "requires": { "babel-code-frame": "6.26.0", "babel-messages": "6.23.0", @@ -1101,7 +1104,6 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "dev": true, "requires": { "babel-runtime": "6.26.0", "esutils": "2.0.2", @@ -1112,8 +1114,7 @@ "babylon": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" }, "balanced-match": { "version": "1.0.0", @@ -1674,7 +1675,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, "requires": { "ansi-styles": "2.2.1", "escape-string-regexp": "1.0.5", @@ -2505,7 +2505,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -2934,8 +2933,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "escodegen": { "version": "1.9.1", @@ -5178,8 +5176,7 @@ "globals": { "version": "9.18.0", "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" }, "globby": { "version": "5.0.0", @@ -5598,7 +5595,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, "requires": { "ansi-regex": "2.1.1" } @@ -6329,7 +6325,6 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.3.tgz", "integrity": "sha512-7Z5PPegwDTyjbaeCnV0efcyS6vdKAU51kpEmS7QFib3P4822l8ICYyMn7qvJnc+WzLoDsuI9gPMKbJ8pCu8XtA==", - "dev": true, "requires": { "loose-envify": "1.3.1" } @@ -6747,8 +6742,7 @@ "js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" }, "js-yaml": { "version": "3.7.0", @@ -7459,7 +7453,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", - "dev": true, "requires": { "js-tokens": "3.0.2" } @@ -7855,8 +7848,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "multicast-dns": { "version": "6.2.3", @@ -11251,7 +11243,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, "requires": { "ansi-regex": "2.1.1" } @@ -11322,8 +11313,7 @@ "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" }, "svgo": { "version": "0.7.2", @@ -11537,8 +11527,7 @@ "to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" }, "to-object-path": { "version": "0.3.0", diff --git a/package.json b/package.json index ff567519..635d47cc 100644 --- a/package.json +++ b/package.json @@ -68,6 +68,7 @@ }, "dependencies": { "babel-polyfill": "^6.26.0", + "babel-plugin-transform-builtin-extend": "1.1.2", "bcryptjs": "^2.4.3", "bignumber.js": "^6.0.0", "bootstrap": "^3.3.7", diff --git a/src/core/Recipe.mjs b/src/core/Recipe.mjs index 95dab22b..808a97b0 100755 --- a/src/core/Recipe.mjs +++ b/src/core/Recipe.mjs @@ -8,6 +8,7 @@ import OpModules from "./config/modules/OpModules"; import OperationConfig from "./config/OperationConfig.json"; import log from "loglevel"; +import OperationError from "./errors/OperationError"; /** * The Recipe controls a list of Operations and the Dish they operate on. @@ -175,18 +176,24 @@ class Recipe { dish.set(output, op.outputType); } } catch (err) { - const e = typeof err == "string" ? { message: err } : err; - - e.progress = i; - if (e.fileName) { - e.displayStr = op.name + " - " + e.name + " in " + - e.fileName + " on line " + e.lineNumber + - ".

Message: " + (e.displayStr || e.message); + // print expected errors in output pane + if (err instanceof OperationError) { + dish.set(err.message, "string"); + return i; } else { - e.displayStr = op.name + " - " + (e.displayStr || e.message); - } + const e = typeof err == "string" ? { message: err } : err; - throw e; + e.progress = i; + if (e.fileName) { + e.displayStr = op.name + " - " + e.name + " in " + + e.fileName + " on line " + e.lineNumber + + ".

Message: " + (e.displayStr || e.message); + } else { + e.displayStr = op.name + " - " + (e.displayStr || e.message); + } + + throw e; + } } } diff --git a/src/core/errors/OperationError.mjs b/src/core/errors/OperationError.mjs new file mode 100644 index 00000000..a87f3978 --- /dev/null +++ b/src/core/errors/OperationError.mjs @@ -0,0 +1,20 @@ +/** + * Create custom error type for handling operation input errors. + * i.e. where the operation can handle the error and print a + * message to the screen. + */ +class OperationError extends Error { + /** + * Standard error constructor. Adds no new behaviour. + * @param args standard error args + */ + constructor(...args) { + super(...args); + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, OperationError); + } + } +} + +export default OperationError; diff --git a/src/core/operations/CartesianProduct.mjs b/src/core/operations/CartesianProduct.mjs index 5cf546b0..5125511b 100644 --- a/src/core/operations/CartesianProduct.mjs +++ b/src/core/operations/CartesianProduct.mjs @@ -5,6 +5,7 @@ */ import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; /** * Set cartesian product operation @@ -44,7 +45,8 @@ class CartesianProduct extends Operation { */ validateSampleNumbers(sets) { if (!sets || sets.length < 2) { - throw "Incorrect number of sets, perhaps you need to modify the sample delimiter or add more samples?"; + throw new OperationError("Incorrect number of sets, perhaps you" + + " need to modify the sample delimiter or add more samples?"); } } @@ -54,16 +56,13 @@ class CartesianProduct extends Operation { * @param {string} input * @param {Object[]} args * @returns {string} + * @throws {OperationError} */ run(input, args) { [this.sampleDelim, this.itemDelimiter] = args; const sets = input.split(this.sampleDelim); - try { - this.validateSampleNumbers(sets); - } catch (e) { - return e; - } + this.validateSampleNumbers(sets); return this.runCartesianProduct(...sets.map(s => s.split(this.itemDelimiter))); } diff --git a/src/core/operations/SetDifference.mjs b/src/core/operations/SetDifference.mjs index 4b0f3118..0962fda2 100644 --- a/src/core/operations/SetDifference.mjs +++ b/src/core/operations/SetDifference.mjs @@ -5,6 +5,7 @@ */ import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; /** * Set Difference operation @@ -44,7 +45,7 @@ class SetDifference extends Operation { */ validateSampleNumbers(sets) { if (!sets || (sets.length !== 2)) { - throw "Incorrect number of sets, perhaps you need to modify the sample delimiter or add more samples?"; + throw new OperationError("Incorrect number of sets, perhaps you need to modify the sample delimiter or add more samples?"); } } @@ -54,16 +55,13 @@ class SetDifference extends Operation { * @param {string} input * @param {Object[]} args * @returns {string} + * @throws {OperationError} */ run(input, args) { [this.sampleDelim, this.itemDelimiter] = args; const sets = input.split(this.sampleDelim); - try { - this.validateSampleNumbers(sets); - } catch (e) { - return e; - } + this.validateSampleNumbers(sets); return this.runSetDifference(...sets.map(s => s.split(this.itemDelimiter))); } diff --git a/src/core/operations/SetIntersection.mjs b/src/core/operations/SetIntersection.mjs index e576be07..4ede1f98 100644 --- a/src/core/operations/SetIntersection.mjs +++ b/src/core/operations/SetIntersection.mjs @@ -5,6 +5,7 @@ */ import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; /** * Set Intersection operation @@ -44,7 +45,7 @@ class SetIntersection extends Operation { */ validateSampleNumbers(sets) { if (!sets || (sets.length !== 2)) { - throw "Incorrect number of sets, perhaps you need to modify the sample delimiter or add more samples?"; + throw new OperationError("Incorrect number of sets, perhaps you need to modify the sample delimiter or add more samples?"); } } @@ -54,16 +55,13 @@ class SetIntersection extends Operation { * @param {string} input * @param {Object[]} args * @returns {string} + * @throws {OperationError} */ run(input, args) { [this.sampleDelim, this.itemDelimiter] = args; const sets = input.split(this.sampleDelim); - try { - this.validateSampleNumbers(sets); - } catch (e) { - return e; - } + this.validateSampleNumbers(sets); return this.runIntersect(...sets.map(s => s.split(this.itemDelimiter))); } diff --git a/src/core/operations/SetUnion.mjs b/src/core/operations/SetUnion.mjs index 56e12f4d..6975ffb5 100644 --- a/src/core/operations/SetUnion.mjs +++ b/src/core/operations/SetUnion.mjs @@ -5,6 +5,7 @@ */ import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; /** * Set Union operation @@ -44,7 +45,7 @@ class SetUnion extends Operation { */ validateSampleNumbers(sets) { if (!sets || (sets.length !== 2)) { - throw "Incorrect number of sets, perhaps you need to modify the sample delimiter or add more samples?"; + throw new OperationError("Incorrect number of sets, perhaps you need to modify the sample delimiter or add more samples?"); } } @@ -54,16 +55,13 @@ class SetUnion extends Operation { * @param {string} input * @param {Object[]} args * @returns {string} + * @throws {OperationError} */ run(input, args) { [this.sampleDelim, this.itemDelimiter] = args; const sets = input.split(this.sampleDelim); - try { - this.validateSampleNumbers(sets); - } catch (e) { - return e; - } + this.validateSampleNumbers(sets); return this.runUnion(...sets.map(s => s.split(this.itemDelimiter))); } diff --git a/src/core/operations/SymmetricDifference.mjs b/src/core/operations/SymmetricDifference.mjs index bc2bb434..071a49d4 100644 --- a/src/core/operations/SymmetricDifference.mjs +++ b/src/core/operations/SymmetricDifference.mjs @@ -6,6 +6,7 @@ import Utils from "../Utils"; import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; /** * Set Symmetric Difference operation @@ -45,7 +46,7 @@ class SymmetricDifference extends Operation { */ validateSampleNumbers(sets) { if (!sets || (sets.length !== 2)) { - throw "Incorrect number of sets, perhaps you need to modify the sample delimiter or add more samples?"; + throw new OperationError("Incorrect number of sets, perhaps you need to modify the sample delimiter or add more samples?"); } } @@ -55,16 +56,13 @@ class SymmetricDifference extends Operation { * @param {string} input * @param {Object[]} args * @returns {string} + * @throws {OperationError} */ run(input, args) { [this.sampleDelim, this.itemDelimiter] = args; const sets = input.split(this.sampleDelim); - try { - this.validateSampleNumbers(sets); - } catch (e) { - return e; - } + this.validateSampleNumbers(sets); return this.runSymmetricDifference(...sets.map(s => s.split(this.itemDelimiter))); }