Browse Source

Added 'DishError' and refined test results.

n1474335 6 years ago
parent
commit
b29bb6fdd7

+ 79 - 70
src/core/Dish.mjs

@@ -6,6 +6,7 @@
  */
 
 import Utils from "./Utils";
+import DishError from "./errors/DishError";
 import BigNumber from "bignumber.js";
 import log from "loglevel";
 
@@ -61,7 +62,7 @@ class Dish {
             case "list<file>":
                 return Dish.LIST_FILE;
             default:
-                throw "Invalid data type string. No matching enum.";
+                throw new DishError("Invalid data type string. No matching enum.");
         }
     }
 
@@ -93,7 +94,7 @@ class Dish {
             case Dish.LIST_FILE:
                 return "List<File>";
             default:
-                throw "Invalid data type enum. No matching type.";
+                throw new DishError("Invalid data type enum. No matching type.");
         }
     }
 
@@ -117,7 +118,7 @@ class Dish {
 
         if (!this.valid()) {
             const sample = Utils.truncate(JSON.stringify(this.value), 13);
-            throw "Data is not a valid " + Dish.enumLookup(type) + ": " + sample;
+            throw new DishError(`Data is not a valid ${Dish.enumLookup(type)}: ${sample}`);
         }
     }
 
@@ -151,77 +152,85 @@ class Dish {
         const byteArrayToStr = notUTF8 ? Utils.byteArrayToChars : Utils.byteArrayToUtf8;
 
         // Convert data to intermediate byteArray type
-        switch (this.type) {
-            case Dish.STRING:
-                this.value = this.value ? Utils.strToByteArray(this.value) : [];
-                break;
-            case Dish.NUMBER:
-                this.value = typeof this.value === "number" ? Utils.strToByteArray(this.value.toString()) : [];
-                break;
-            case Dish.HTML:
-                this.value = this.value ? Utils.strToByteArray(Utils.unescapeHtml(Utils.stripHtmlTags(this.value, true))) : [];
-                break;
-            case Dish.ARRAY_BUFFER:
-                // Array.from() would be nicer here, but it's slightly slower
-                this.value = Array.prototype.slice.call(new Uint8Array(this.value));
-                break;
-            case Dish.BIG_NUMBER:
-                this.value = this.value instanceof BigNumber ? Utils.strToByteArray(this.value.toFixed()) : [];
-                break;
-            case Dish.JSON:
-                this.value = this.value ? Utils.strToByteArray(JSON.stringify(this.value, null, 4)) : [];
-                break;
-            case Dish.FILE:
-                this.value = await Utils.readFile(this.value);
-                this.value = Array.prototype.slice.call(this.value);
-                break;
-            case Dish.LIST_FILE:
-                this.value = await Promise.all(this.value.map(async f => Utils.readFile(f)));
-                this.value = this.value.map(b => Array.prototype.slice.call(b));
-                this.value = [].concat.apply([], this.value);
-                break;
-            default:
-                break;
+        try {
+            switch (this.type) {
+                case Dish.STRING:
+                    this.value = this.value ? Utils.strToByteArray(this.value) : [];
+                    break;
+                case Dish.NUMBER:
+                    this.value = typeof this.value === "number" ? Utils.strToByteArray(this.value.toString()) : [];
+                    break;
+                case Dish.HTML:
+                    this.value = this.value ? Utils.strToByteArray(Utils.unescapeHtml(Utils.stripHtmlTags(this.value, true))) : [];
+                    break;
+                case Dish.ARRAY_BUFFER:
+                    // Array.from() would be nicer here, but it's slightly slower
+                    this.value = Array.prototype.slice.call(new Uint8Array(this.value));
+                    break;
+                case Dish.BIG_NUMBER:
+                    this.value = this.value instanceof BigNumber ? Utils.strToByteArray(this.value.toFixed()) : [];
+                    break;
+                case Dish.JSON:
+                    this.value = this.value ? Utils.strToByteArray(JSON.stringify(this.value, null, 4)) : [];
+                    break;
+                case Dish.FILE:
+                    this.value = await Utils.readFile(this.value);
+                    this.value = Array.prototype.slice.call(this.value);
+                    break;
+                case Dish.LIST_FILE:
+                    this.value = await Promise.all(this.value.map(async f => Utils.readFile(f)));
+                    this.value = this.value.map(b => Array.prototype.slice.call(b));
+                    this.value = [].concat.apply([], this.value);
+                    break;
+                default:
+                    break;
+            }
+        } catch (err) {
+            throw new DishError(`Error translating from ${Dish.enumLookup(this.type)} to byteArray: ${err}`);
         }
 
         this.type = Dish.BYTE_ARRAY;
 
         // Convert from byteArray to toType
-        switch (toType) {
-            case Dish.STRING:
-            case Dish.HTML:
-                this.value = this.value ? byteArrayToStr(this.value) : "";
-                this.type = Dish.STRING;
-                break;
-            case Dish.NUMBER:
-                this.value = this.value ? parseFloat(byteArrayToStr(this.value)) : 0;
-                this.type = Dish.NUMBER;
-                break;
-            case Dish.ARRAY_BUFFER:
-                this.value = new Uint8Array(this.value).buffer;
-                this.type = Dish.ARRAY_BUFFER;
-                break;
-            case Dish.BIG_NUMBER:
-                try {
-                    this.value = new BigNumber(byteArrayToStr(this.value));
-                } catch (err) {
-                    this.value = new BigNumber(NaN);
-                }
-                this.type = Dish.BIG_NUMBER;
-                break;
-            case Dish.JSON:
-                this.value = JSON.parse(byteArrayToStr(this.value));
-                this.type = Dish.JSON;
-                break;
-            case Dish.FILE:
-                this.value = new File(this.value, "unknown");
-                break;
-            case Dish.LIST_FILE:
-                this.value = [new File(this.value, "unknown")];
-                this.type = Dish.LIST_FILE;
-                break;
-            default:
-                break;
+        try {
+            switch (toType) {
+                case Dish.STRING:
+                case Dish.HTML:
+                    this.value = this.value ? byteArrayToStr(this.value) : "";
+                    this.type = Dish.STRING;
+                    break;
+                case Dish.NUMBER:
+                    this.value = this.value ? parseFloat(byteArrayToStr(this.value)) : 0;
+                    this.type = Dish.NUMBER;
+                    break;
+                case Dish.ARRAY_BUFFER:
+                    this.value = new Uint8Array(this.value).buffer;
+                    this.type = Dish.ARRAY_BUFFER;
+                    break;
+                case Dish.BIG_NUMBER:
+                    try {
+                        this.value = new BigNumber(byteArrayToStr(this.value));
+                    } catch (err) {
+                        this.value = new BigNumber(NaN);
+                    }
+                    this.type = Dish.BIG_NUMBER;
+                    break;
+                case Dish.JSON:
+                    this.value = JSON.parse(byteArrayToStr(this.value));
+                    this.type = Dish.JSON;
+                    break;
+                case Dish.FILE:
+                    this.value = new File(this.value, "unknown");
+                    break;
+                case Dish.LIST_FILE:
+                    this.value = [new File(this.value, "unknown")];
+                    this.type = Dish.LIST_FILE;
+                    break;
+                default:
+                    break;
+            }
+        } catch (err) {
+            throw new DishError(`Error translating from byteArray to ${Dish.enumLookup(toType)}: ${err}`);
         }
     }
 
@@ -357,7 +366,7 @@ class Dish {
                 );
                 break;
             default:
-                throw new Error("Cannot clone Dish, unknown type");
+                throw new DishError("Cannot clone Dish, unknown type");
         }
 
         return newDish;

+ 5 - 1
src/core/Recipe.mjs

@@ -4,10 +4,10 @@
  * @license Apache-2.0
  */
 
-// import Operation from "./Operation.js";
 import OpModules from "./config/modules/OpModules";
 import OperationConfig from "./config/OperationConfig.json";
 import OperationError from "./errors/OperationError";
+import DishError from "./errors/DishError";
 import log from "loglevel";
 
 /**
@@ -183,6 +183,10 @@ class Recipe  {
                     // native types is not fully supported yet.
                     dish.set(err.message, "string");
                     return i;
+                } else if (err instanceof DishError ||
+                    (err.type && err.type === "DishError")) {
+                    dish.set(err.message, "string");
+                    return i;
                 } else {
                     const e = typeof err == "string" ? { message: err } : err;
 

+ 26 - 0
src/core/errors/DishError.mjs

@@ -0,0 +1,26 @@
+/**
+ * Custom error type for handling Dish type errors.
+ * i.e. where the Dish cannot be successfully translated between types
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+class DishError extends Error {
+    /**
+     * Standard error constructor. Adds no new behaviour.
+     *
+     * @param args - Standard error args
+     */
+    constructor(...args) {
+        super(...args);
+
+        this.type = "DishError";
+
+        if (Error.captureStackTrace) {
+            Error.captureStackTrace(this, DishError);
+        }
+    }
+}
+
+export default DishError;

+ 1 - 1
src/core/operations/ToMessagePack.mjs

@@ -5,7 +5,7 @@
  */
 
 import Operation from "../Operation";
-import OperationError from "../errors/OperationError.mjs";
+import OperationError from "../errors/OperationError";
 import notepack from "notepack.io";
 
 /**

+ 1 - 1
src/core/vendor/remove-exif.mjs

@@ -18,7 +18,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 */
 
-import Utils from "../Utils.mjs";
+import Utils from "../Utils";
 
 // Param jpeg should be a binaryArray
 export function removeEXIF(jpeg) {

+ 3 - 2
test/index.mjs

@@ -77,7 +77,7 @@ import "./tests/operations/SetUnion";
 import "./tests/operations/StrUtils";
 import "./tests/operations/SymmetricDifference";
 import "./tests/operations/TextEncodingBruteForce";
-import "./tests/operations/ToGeohash.mjs";
+import "./tests/operations/ToGeohash";
 import "./tests/operations/TranslateDateTimeFormat";
 import "./tests/operations/Magic";
 import "./tests/operations/ParseTLV";
@@ -155,7 +155,8 @@ TestRegister.runTests()
         }
 
         if (!allTestsPassing) {
-            console.log("\nNot all tests are passing");
+            console.log("\nFailing tests:\n");
+            results.filter(r => r.status !== "passing").forEach(handleTestResult);
         }
 
         process.exit(allTestsPassing ? 0 : 1);

+ 2 - 2
test/tests/operations/Code.mjs

@@ -334,8 +334,8 @@ TestRegister.addTests([
     },
     {
         name: "To MessagePack: no content",
-        input: "",
-        expectedError: true,
+        input: "{}",
+        expectedMatch: /Unexpected end of JSON input/,
         recipeConfig: [
             {
                 "op": "To MessagePack",