Changed all error returns to OperationErrors

This commit is contained in:
Matt C 2018-05-15 18:01:04 +01:00
parent b3ee251ee3
commit 2e4f5b7070
25 changed files with 88 additions and 35 deletions

View File

@ -7,6 +7,7 @@
import Operation from "../Operation"; import Operation from "../Operation";
import Utils from "../Utils"; import Utils from "../Utils";
import forge from "node-forge/dist/forge.min.js"; import forge from "node-forge/dist/forge.min.js";
import OperationError from "../errors/OperationError";
/** /**
* AES Decrypt operation * AES Decrypt operation
@ -65,6 +66,8 @@ class AESDecrypt extends Operation {
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {string} * @returns {string}
*
* @throws {OperationError} if cannot decrypt input or invalid key length
*/ */
run(input, args) { run(input, args) {
const key = Utils.convertToByteArray(args[0].string, args[0].option), const key = Utils.convertToByteArray(args[0].string, args[0].option),
@ -75,12 +78,12 @@ class AESDecrypt extends Operation {
gcmTag = Utils.convertToByteString(args[5].string, args[5].option); gcmTag = Utils.convertToByteString(args[5].string, args[5].option);
if ([16, 24, 32].indexOf(key.length) < 0) { if ([16, 24, 32].indexOf(key.length) < 0) {
return `Invalid key length: ${key.length} bytes throw new OperationError(`Invalid key length: ${key.length} bytes
The following algorithms will be used based on the size of the key: The following algorithms will be used based on the size of the key:
16 bytes = AES-128 16 bytes = AES-128
24 bytes = AES-192 24 bytes = AES-192
32 bytes = AES-256`; 32 bytes = AES-256`);
} }
input = Utils.convertToByteString(input, inputType); input = Utils.convertToByteString(input, inputType);
@ -96,7 +99,7 @@ The following algorithms will be used based on the size of the key:
if (result) { if (result) {
return outputType === "Hex" ? decipher.output.toHex() : decipher.output.getBytes(); return outputType === "Hex" ? decipher.output.toHex() : decipher.output.getBytes();
} else { } else {
return "Unable to decrypt input with these parameters."; throw new OperationError("Unable to decrypt input with these parameters.");
} }
} }

View File

@ -7,6 +7,7 @@
import Operation from "../Operation"; import Operation from "../Operation";
import Utils from "../Utils"; import Utils from "../Utils";
import forge from "node-forge/dist/forge.min.js"; import forge from "node-forge/dist/forge.min.js";
import OperationError from "../errors/OperationError";
/** /**
* AES Encrypt operation * AES Encrypt operation
@ -59,6 +60,8 @@ class AESEncrypt extends Operation {
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {string} * @returns {string}
*
* @throws {OperationError} if invalid key length
*/ */
run(input, args) { run(input, args) {
const key = Utils.convertToByteArray(args[0].string, args[0].option), const key = Utils.convertToByteArray(args[0].string, args[0].option),
@ -68,12 +71,12 @@ class AESEncrypt extends Operation {
outputType = args[4]; outputType = args[4];
if ([16, 24, 32].indexOf(key.length) < 0) { if ([16, 24, 32].indexOf(key.length) < 0) {
return `Invalid key length: ${key.length} bytes throw new OperationError(`Invalid key length: ${key.length} bytes
The following algorithms will be used based on the size of the key: The following algorithms will be used based on the size of the key:
16 bytes = AES-128 16 bytes = AES-128
24 bytes = AES-192 24 bytes = AES-192
32 bytes = AES-256`; 32 bytes = AES-256`);
} }
input = Utils.convertToByteString(input, inputType); input = Utils.convertToByteString(input, inputType);

View File

@ -42,6 +42,8 @@ class AffineCipherDecode extends Operation {
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {string} * @returns {string}
*
* @throws {OperationError} if a or b values are invalid
*/ */
run(input, args) { run(input, args) {
const alphabet = "abcdefghijklmnopqrstuvwxyz", const alphabet = "abcdefghijklmnopqrstuvwxyz",

View File

@ -37,6 +37,8 @@ class BifidCipherDecode extends Operation {
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {string} * @returns {string}
*
* @throws {OperationError} if invalid key
*/ */
run(input, args) { run(input, args) {
const keywordStr = args[0].toUpperCase().replace("J", "I"), const keywordStr = args[0].toUpperCase().replace("J", "I"),

View File

@ -37,6 +37,8 @@ class BifidCipherEncode extends Operation {
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {string} * @returns {string}
*
* @throws {OperationError} if key is invalid
*/ */
run(input, args) { run(input, args) {
const keywordStr = args[0].toUpperCase().replace("J", "I"), const keywordStr = args[0].toUpperCase().replace("J", "I"),

View File

@ -41,7 +41,7 @@ class CartesianProduct extends Operation {
* Validate input length * Validate input length
* *
* @param {Object[]} sets * @param {Object[]} sets
* @throws {Error} if fewer than 2 sets * @throws {OperationError} if fewer than 2 sets
*/ */
validateSampleNumbers(sets) { validateSampleNumbers(sets) {
if (!sets || sets.length < 2) { if (!sets || sets.length < 2) {

View File

@ -6,6 +6,8 @@
import Operation from "../Operation"; import Operation from "../Operation";
import * as disassemble from "../vendor/DisassembleX86-64"; import * as disassemble from "../vendor/DisassembleX86-64";
import OperationError from "../errors/OperationError";
/** /**
* Disassemble x86 operation * Disassemble x86 operation
*/ */
@ -68,6 +70,8 @@ class DisassembleX86 extends Operation {
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {string} * @returns {string}
*
* @throws {OperationError} if invalid mode value
*/ */
run(input, args) { run(input, args) {
const mode = args[0], const mode = args[0],
@ -88,7 +92,7 @@ class DisassembleX86 extends Operation {
disassemble.setBitMode(0); disassemble.setBitMode(0);
break; break;
default: default:
throw "Invalid mode value"; throw new OperationError("Invalid mode value");
} }
switch (compatibility) { switch (compatibility) {

View File

@ -5,6 +5,7 @@
*/ */
import Operation from "../Operation"; import Operation from "../Operation";
import OperationError from "../errors/OperationError";
/** /**
* Drop bytes operation * Drop bytes operation
@ -45,6 +46,8 @@ class DropBytes extends Operation {
* @param {ArrayBuffer} input * @param {ArrayBuffer} input
* @param {Object[]} args * @param {Object[]} args
* @returns {ArrayBuffer} * @returns {ArrayBuffer}
*
* @throws {OperationError} if invalid input
*/ */
run(input, args) { run(input, args) {
const start = args[0], const start = args[0],
@ -52,7 +55,7 @@ class DropBytes extends Operation {
applyToEachLine = args[2]; applyToEachLine = args[2];
if (start < 0 || length < 0) if (start < 0 || length < 0)
throw "Error: Invalid value"; throw new OperationError("Error: Invalid value");
if (!applyToEachLine) { if (!applyToEachLine) {
const left = input.slice(0, start), const left = input.slice(0, start),

View File

@ -7,6 +7,7 @@
import Operation from "../Operation"; import Operation from "../Operation";
import Utils from "../Utils"; import Utils from "../Utils";
import {INPUT_DELIM_OPTIONS} from "../lib/Delim"; import {INPUT_DELIM_OPTIONS} from "../lib/Delim";
import OperationError from "../errors/OperationError";
/** /**
* Filter operation * Filter operation
@ -56,7 +57,7 @@ class Filter extends Operation {
try { try {
regex = new RegExp(args[1]); regex = new RegExp(args[1]);
} catch (err) { } catch (err) {
return "Invalid regex. Details: " + err.message; throw new OperationError(`Invalid regex. Details: ${err.message}`);
} }
const regexFilter = function(value) { const regexFilter = function(value) {

View File

@ -7,6 +7,7 @@
import Operation from "../Operation"; import Operation from "../Operation";
import Utils from "../Utils"; import Utils from "../Utils";
import {DELIM_OPTIONS} from "../lib/Delim"; import {DELIM_OPTIONS} from "../lib/Delim";
import OperationError from "../errors/OperationError";
/** /**
* From Charcode operation * From Charcode operation
@ -42,6 +43,8 @@ class FromCharcode extends Operation {
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {byteArray} * @returns {byteArray}
*
* @throws {OperationError} if base out of range
*/ */
run(input, args) { run(input, args) {
const delim = Utils.charRep(args[0] || "Space"), const delim = Utils.charRep(args[0] || "Space"),
@ -50,7 +53,7 @@ class FromCharcode extends Operation {
i = 0; i = 0;
if (base < 2 || base > 36) { if (base < 2 || base > 36) {
throw "Error: Base argument must be between 2 and 36"; throw new OperationError("Error: Base argument must be between 2 and 36");
} }
if (input.length === 0) { if (input.length === 0) {

View File

@ -7,6 +7,7 @@
import Operation from "../Operation"; import Operation from "../Operation";
import moment from "moment-timezone"; import moment from "moment-timezone";
import {UNITS} from "../lib/DateTime"; import {UNITS} from "../lib/DateTime";
import OperationError from "../errors/OperationError";
/** /**
* From UNIX Timestamp operation * From UNIX Timestamp operation
@ -37,6 +38,8 @@ class FromUNIXTimestamp extends Operation {
* @param {number} input * @param {number} input
* @param {Object[]} args * @param {Object[]} args
* @returns {string} * @returns {string}
*
* @throws {OperationError} if invalid unit
*/ */
run(input, args) { run(input, args) {
const units = args[0]; const units = args[0];
@ -57,7 +60,7 @@ class FromUNIXTimestamp extends Operation {
d = moment(input / 1000000); d = moment(input / 1000000);
return d.tz("UTC").format("ddd D MMMM YYYY HH:mm:ss.SSS") + " UTC"; return d.tz("UTC").format("ddd D MMMM YYYY HH:mm:ss.SSS") + " UTC";
} else { } else {
throw "Unrecognised unit"; throw new OperationError("Unrecognised unit");
} }
} }

View File

@ -7,6 +7,7 @@
import Operation from "../Operation"; import Operation from "../Operation";
import Utils from "../Utils"; import Utils from "../Utils";
import {fromHex} from "../lib/Hex"; import {fromHex} from "../lib/Hex";
import OperationError from "../errors/OperationError";
/** /**
* Hamming Distance operation * Hamming Distance operation
@ -55,11 +56,11 @@ class HammingDistance extends Operation {
samples = input.split(delim); samples = input.split(delim);
if (samples.length !== 2) { if (samples.length !== 2) {
return "Error: You can only calculae the edit distance between 2 strings. Please ensure exactly two inputs are provided, separated by the specified delimiter."; throw new OperationError("Error: You can only calculae the edit distance between 2 strings. Please ensure exactly two inputs are provided, separated by the specified delimiter.");
} }
if (samples[0].length !== samples[1].length) { if (samples[0].length !== samples[1].length) {
return "Error: Both inputs must be of the same length."; throw new OperationError("Error: Both inputs must be of the same length.");
} }
if (inputType === "Hex") { if (inputType === "Hex") {

View File

@ -6,6 +6,7 @@
import Operation from "../Operation"; import Operation from "../Operation";
import Utils from "../Utils"; import Utils from "../Utils";
import OperationError from "../errors/OperationError";
/** /**
* Offset checker operation * Offset checker operation
@ -48,7 +49,7 @@ class OffsetChecker extends Operation {
chr; chr;
if (!samples || samples.length < 2) { if (!samples || samples.length < 2) {
return "Not enough samples, perhaps you need to modify the sample delimiter or add more data?"; throw new OperationError("Not enough samples, perhaps you need to modify the sample delimiter or add more data?");
} }
// Initialise output strings // Initialise output strings

View File

@ -7,9 +7,11 @@
import Operation from "../Operation"; import Operation from "../Operation";
import kbpgp from "kbpgp"; import kbpgp from "kbpgp";
import { ASP, importPrivateKey } from "../lib/PGP"; import { ASP, importPrivateKey } from "../lib/PGP";
import OperationError from "../errors/OperationError";
import promisifyDefault from "es6-promisify"; import promisifyDefault from "es6-promisify";
const promisify = promisifyDefault.promisify; const promisify = promisifyDefault.promisify;
/** /**
* PGP Decrypt operation * PGP Decrypt operation
*/ */
@ -44,6 +46,8 @@ class PGPDecrypt extends Operation {
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {string} * @returns {string}
*
* @throws {OperationError} if invalid private key
*/ */
async run(input, args) { async run(input, args) {
const encryptedMessage = input, const encryptedMessage = input,
@ -52,7 +56,7 @@ class PGPDecrypt extends Operation {
keyring = new kbpgp.keyring.KeyRing(); keyring = new kbpgp.keyring.KeyRing();
let plaintextMessage; let plaintextMessage;
if (!privateKey) return "Enter the private key of the recipient."; if (!privateKey) throw new OperationError("Enter the private key of the recipient.");
const key = await importPrivateKey(privateKey, passphrase); const key = await importPrivateKey(privateKey, passphrase);
keyring.add_key_manager(key); keyring.add_key_manager(key);
@ -64,7 +68,7 @@ class PGPDecrypt extends Operation {
asp: ASP asp: ASP
}); });
} catch (err) { } catch (err) {
throw `Couldn't decrypt message with provided private key: ${err}`; throw new OperationError(`Couldn't decrypt message with provided private key: ${err}`);
} }
return plaintextMessage.toString(); return plaintextMessage.toString();

View File

@ -7,6 +7,7 @@
import Operation from "../Operation"; import Operation from "../Operation";
import kbpgp from "kbpgp"; import kbpgp from "kbpgp";
import { ASP, importPrivateKey, importPublicKey } from "../lib/PGP"; import { ASP, importPrivateKey, importPublicKey } from "../lib/PGP";
import OperationError from "../errors/OperationError";
import promisifyDefault from "es6-promisify"; import promisifyDefault from "es6-promisify";
const promisify = promisifyDefault.promisify; const promisify = promisifyDefault.promisify;
@ -58,8 +59,8 @@ class PGPDecryptAndVerify extends Operation {
keyring = new kbpgp.keyring.KeyRing(); keyring = new kbpgp.keyring.KeyRing();
let unboxedLiterals; let unboxedLiterals;
if (!publicKey) return "Enter the public key of the signer."; if (!publicKey) throw new OperationError("Enter the public key of the signer.");
if (!privateKey) return "Enter the private key of the recipient."; if (!privateKey) throw new OperationError("Enter the private key of the recipient.");
const privKey = await importPrivateKey(privateKey, passphrase); const privKey = await importPrivateKey(privateKey, passphrase);
const pubKey = await importPublicKey(publicKey); const pubKey = await importPublicKey(publicKey);
keyring.add_key_manager(privKey); keyring.add_key_manager(privKey);
@ -97,13 +98,13 @@ class PGPDecryptAndVerify extends Operation {
text += unboxedLiterals.toString(); text += unboxedLiterals.toString();
return text.trim(); return text.trim();
} else { } else {
return "Could not identify a key manager."; throw new OperationError("Could not identify a key manager.");
} }
} else { } else {
return "The data does not appear to be signed."; throw new OperationError("The data does not appear to be signed.");
} }
} catch (err) { } catch (err) {
return `Couldn't verify message: ${err}`; throw new OperationError(`Couldn't verify message: ${err}`);
} }
} }

View File

@ -7,8 +7,10 @@
import Operation from "../Operation"; import Operation from "../Operation";
import kbpgp from "kbpgp"; import kbpgp from "kbpgp";
import { ASP } from "../lib/PGP"; import { ASP } from "../lib/PGP";
import OperationError from "../errors/OperationError";
import promisifyDefault from "es6-promisify"; import promisifyDefault from "es6-promisify";
const promisify = promisifyDefault.promisify; const promisify = promisifyDefault.promisify;
/** /**
* PGP Encrypt operation * PGP Encrypt operation
*/ */
@ -38,6 +40,8 @@ class PGPEncrypt extends Operation {
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {string} * @returns {string}
*
* @throws {OperationError} if failed private key import or failed encryption
*/ */
async run(input, args) { async run(input, args) {
const plaintextMessage = input, const plaintextMessage = input,
@ -45,14 +49,14 @@ class PGPEncrypt extends Operation {
let key, let key,
encryptedMessage; encryptedMessage;
if (!plainPubKey) return "Enter the public key of the recipient."; if (!plainPubKey) throw new OperationError("Enter the public key of the recipient.");
try { try {
key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({ key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({
armored: plainPubKey, armored: plainPubKey,
}); });
} catch (err) { } catch (err) {
throw `Could not import public key: ${err}`; throw new OperationError(`Could not import public key: ${err}`);
} }
try { try {
@ -62,7 +66,7 @@ class PGPEncrypt extends Operation {
"asp": ASP "asp": ASP
}); });
} catch (err) { } catch (err) {
throw `Couldn't encrypt message with provided public key: ${err}`; throw new OperationError(`Couldn't encrypt message with provided public key: ${err}`);
} }
return encryptedMessage.toString(); return encryptedMessage.toString();

View File

@ -7,6 +7,7 @@
import Operation from "../Operation"; import Operation from "../Operation";
import kbpgp from "kbpgp"; import kbpgp from "kbpgp";
import { ASP, importPrivateKey, importPublicKey } from "../lib/PGP"; import { ASP, importPrivateKey, importPublicKey } from "../lib/PGP";
import OperationError from "../errors/OperationError";
import promisifyDefault from "es6-promisify"; import promisifyDefault from "es6-promisify";
const promisify = promisifyDefault.promisify; const promisify = promisifyDefault.promisify;
@ -49,6 +50,8 @@ class PGPEncryptAndSign extends Operation {
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {string} * @returns {string}
*
* @throws {OperationError} if failure to sign message
*/ */
async run(input, args) { async run(input, args) {
const message = input, const message = input,
@ -57,8 +60,8 @@ class PGPEncryptAndSign extends Operation {
publicKey = args[2]; publicKey = args[2];
let signedMessage; let signedMessage;
if (!privateKey) return "Enter the private key of the signer."; if (!privateKey) throw new OperationError("Enter the private key of the signer.");
if (!publicKey) return "Enter the public key of the recipient."; if (!publicKey) throw new OperationError("Enter the public key of the recipient.");
const privKey = await importPrivateKey(privateKey, passphrase); const privKey = await importPrivateKey(privateKey, passphrase);
const pubKey = await importPublicKey(publicKey); const pubKey = await importPublicKey(publicKey);
@ -70,7 +73,7 @@ class PGPEncryptAndSign extends Operation {
"asp": ASP "asp": ASP
}); });
} catch (err) { } catch (err) {
throw `Couldn't sign message: ${err}`; throw new OperationError(`Couldn't sign message: ${err}`);
} }
return signedMessage; return signedMessage;

View File

@ -7,6 +7,7 @@
import Operation from "../Operation"; import Operation from "../Operation";
import moment from "moment-timezone"; import moment from "moment-timezone";
import {DATETIME_FORMATS, FORMAT_EXAMPLES} from "../lib/DateTime"; import {DATETIME_FORMATS, FORMAT_EXAMPLES} from "../lib/DateTime";
import OperationError from "../errors/OperationError";
/** /**
* Parse DateTime operation * Parse DateTime operation
@ -59,7 +60,7 @@ class ParseDateTime extends Operation {
date = moment.tz(input, inputFormat, inputTimezone); date = moment.tz(input, inputFormat, inputTimezone);
if (!date || date.format() === "Invalid date") throw Error; if (!date || date.format() === "Invalid date") throw Error;
} catch (err) { } catch (err) {
return "Invalid format.\n\n" + FORMAT_EXAMPLES; throw new OperationError(`Invalid format.\n\n${FORMAT_EXAMPLES}`);
} }
output += "Date: " + date.format("dddd Do MMMM YYYY") + output += "Date: " + date.format("dddd Do MMMM YYYY") +

View File

@ -5,6 +5,7 @@
*/ */
import Operation from "../Operation"; import Operation from "../Operation";
import OperationError from "../errors/OperationError";
/** /**
* Parse UNIX file permissions operation * Parse UNIX file permissions operation
@ -169,7 +170,7 @@ class ParseUNIXFilePermissions extends Operation {
} }
} }
} else { } else {
return "Invalid input format.\nPlease enter the permissions in either octal (e.g. 755) or textual (e.g. drwxr-xr-x) format."; throw new OperationError("Invalid input format.\nPlease enter the permissions in either octal (e.g. 755) or textual (e.g. drwxr-xr-x) format.");
} }
output += "Textual representation: " + permsToStr(perms); output += "Textual representation: " + permsToStr(perms);

View File

@ -7,6 +7,7 @@
import Operation from "../Operation"; import Operation from "../Operation";
import {INFLATE_BUFFER_TYPE} from "../lib/Zlib"; import {INFLATE_BUFFER_TYPE} from "../lib/Zlib";
import rawinflate from "zlibjs/bin/rawinflate.min"; import rawinflate from "zlibjs/bin/rawinflate.min";
import OperationError from "../errors/OperationError";
const Zlib = rawinflate.Zlib; const Zlib = rawinflate.Zlib;
@ -90,7 +91,7 @@ class RawInflate extends Operation {
} }
if (!valid) { if (!valid) {
throw "Error: Unable to inflate data"; throw new OperationError("Error: Unable to inflate data");
} }
} }
// This seems to be the easiest way... // This seems to be the easiest way...

View File

@ -7,6 +7,7 @@
import Operation from "../Operation"; import Operation from "../Operation";
import Utils from "../Utils"; import Utils from "../Utils";
import {fromBase64, toBase64} from "../lib/Base64"; import {fromBase64, toBase64} from "../lib/Base64";
import OperationError from "../errors/OperationError";
/** /**
* Show Base64 offsets operation * Show Base64 offsets operation
@ -58,7 +59,7 @@ class ShowBase64Offsets extends Operation {
script = "<script type='application/javascript'>$('[data-toggle=\"tooltip\"]').tooltip()</script>"; script = "<script type='application/javascript'>$('[data-toggle=\"tooltip\"]').tooltip()</script>";
if (input.length < 1) { if (input.length < 1) {
return "Please enter a string."; throw new OperationError("Please enter a string.");
} }
// Highlight offset 0 // Highlight offset 0

View File

@ -5,6 +5,7 @@
*/ */
import Operation from "../Operation"; import Operation from "../Operation";
import OperationError from "../errors/OperationError";
/** /**
* Take bytes operation * Take bytes operation
@ -45,6 +46,8 @@ class TakeBytes extends Operation {
* @param {ArrayBuffer} input * @param {ArrayBuffer} input
* @param {Object[]} args * @param {Object[]} args
* @returns {ArrayBuffer} * @returns {ArrayBuffer}
*
* @throws {OperationError} if invalid value
*/ */
run(input, args) { run(input, args) {
const start = args[0], const start = args[0],
@ -52,7 +55,7 @@ class TakeBytes extends Operation {
applyToEachLine = args[2]; applyToEachLine = args[2];
if (start < 0 || length < 0) if (start < 0 || length < 0)
throw "Error: Invalid value"; throw new OperationError("Error: Invalid value");
if (!applyToEachLine) if (!applyToEachLine)
return input.slice(start, start+length); return input.slice(start, start+length);

View File

@ -7,6 +7,7 @@
import Operation from "../Operation"; import Operation from "../Operation";
import Utils from "../Utils"; import Utils from "../Utils";
import {DELIM_OPTIONS} from "../lib/Delim"; import {DELIM_OPTIONS} from "../lib/Delim";
import OperationError from "../errors/OperationError";
/** /**
* To Charcode operation * To Charcode operation
@ -42,6 +43,8 @@ class ToCharcode extends Operation {
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {string} * @returns {string}
*
* @throws {OperationError} if base argument out of range
*/ */
run(input, args) { run(input, args) {
const delim = Utils.charRep(args[0] || "Space"), const delim = Utils.charRep(args[0] || "Space"),
@ -51,7 +54,7 @@ class ToCharcode extends Operation {
ordinal; ordinal;
if (base < 2 || base > 36) { if (base < 2 || base > 36) {
throw "Error: Base argument must be between 2 and 36"; throw new OperationError("Error: Base argument must be between 2 and 36");
} }
const charcode = Utils.strToCharcode(input); const charcode = Utils.strToCharcode(input);

View File

@ -7,6 +7,7 @@
import Operation from "../Operation"; import Operation from "../Operation";
import moment from "moment-timezone"; import moment from "moment-timezone";
import {UNITS} from "../lib/DateTime"; import {UNITS} from "../lib/DateTime";
import OperationError from "../errors/OperationError";
/** /**
* To UNIX Timestamp operation * To UNIX Timestamp operation
@ -47,6 +48,8 @@ class ToUNIXTimestamp extends Operation {
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {string} * @returns {string}
*
* @throws {OperationError} if unit unrecognised
*/ */
run(input, args) { run(input, args) {
const [units, treatAsUTC, showDateTime] = args, const [units, treatAsUTC, showDateTime] = args,
@ -63,7 +66,7 @@ class ToUNIXTimestamp extends Operation {
} else if (units === "Nanoseconds (ns)") { } else if (units === "Nanoseconds (ns)") {
result = d.valueOf() * 1000000; result = d.valueOf() * 1000000;
} else { } else {
throw "Unrecognised unit"; throw new OperationError("Unrecognised unit");
} }
return showDateTime ? `${result} (${d.tz("UTC").format("ddd D MMMM YYYY HH:mm:ss")} UTC)` : result.toString(); return showDateTime ? `${result} (${d.tz("UTC").format("ddd D MMMM YYYY HH:mm:ss")} UTC)` : result.toString();

View File

@ -67,7 +67,7 @@ class TranslateDateTimeFormat extends Operation {
date = moment.tz(input, inputFormat, inputTimezone); date = moment.tz(input, inputFormat, inputTimezone);
if (!date || date.format() === "Invalid date") throw Error; if (!date || date.format() === "Invalid date") throw Error;
} catch (err) { } catch (err) {
return "Invalid format.\n\n" + FORMAT_EXAMPLES; throw new OperationError(`Invalid format.\n\n${FORMAT_EXAMPLES}`);
} }
return date.tz(outputTimezone).format(outputFormat); return date.tz(outputTimezone).format(outputFormat);