Skip to content

Commit

Permalink
More robust undefined value checking for format()
Browse files Browse the repository at this point in the history
  • Loading branch information
dhoulb committed Apr 2, 2018
1 parent ad2fae3 commit 988c34a
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 15 deletions.
2 changes: 0 additions & 2 deletions lib/errors/BlorkError.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ const ValueError = require("./ValueError");
* - The type you're checking against (not the value you're checking) is invalid or doesn't exist.
*/
class BlorkError extends ValueError {}
BlorkError.name = "BlorkError";
BlorkError.message = "Incorrect Blork configuration";

// Exports.
module.exports = BlorkError;
18 changes: 11 additions & 7 deletions lib/errors/ValueError.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,20 @@ class ValueError extends TypeError {
* @param {mixed} value A value to debug shown at the end of the message, e.g. "Must be string (received 123)"
* @param {string} prefix=undefined An optional prefix for the message e.g. the function name or the name of the value, e.g. "name: Must be string (received 123)"
*/
constructor(message, value = format.UNDEF, prefix = format.UNDEF) {
// Save message as normal.
super(format(message, value, prefix));
constructor(message = "Invalid value", value = undefined, prefix = "") {
// Save message through TypeError.
// We format immediately (rather than in toString) because Jest (and presumably others) call .message directly.
super(arguments.length > 1 ? format(message, value, prefix) : message);

// Save value separately.
if (value !== format.UNDEF) this.value = value;
// Save parts separately.
this.prefix = prefix;
this.reason = message;
if (arguments.length > 1) this.value = value;

// Save name as constructor name (e.g. ValueError).
this.name = this.constructor.name;
}
}
ValueError.name = "ValueError";
ValueError.message = "Invalid value";

// Exports.
module.exports = ValueError;
8 changes: 2 additions & 6 deletions lib/functions/format.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
const debug = require("./debug");

// Constants.
const UNDEF = Symbol("UNDEF");

/**
* Format an error message.
* Optionally with a prefix and a variable to debug.
Expand All @@ -12,15 +9,14 @@ const UNDEF = Symbol("UNDEF");
* @param {string} prefix=undefined An optional prefix for the message e.g. the function name or the name of the value, e.g. "name: Must be string (received 123)"
* @returns {string} The error message.
*/
function format(message, value = UNDEF, prefix = UNDEF) {
function format(message, value, prefix) {
// e.g. MyPrefix: Must be string (received 123)
return (
(typeof prefix === "string" && prefix.length > 0 ? `${prefix}: ` : "") +
message +
(value !== UNDEF ? ` (received ${debug(value)})` : "")
(arguments.length > 1 ? ` (received ${debug(value)})` : "")
);
}

// Exports.
module.exports = format;
module.exports.UNDEF = UNDEF;
14 changes: 14 additions & 0 deletions test/errors/BlorkError.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,27 @@ const BlorkError = require("../../lib/errors/BlorkError");

// Tests.
describe("BlorkError()", () => {
test("Return correct error with default message", () => {
expect(new BlorkError()).toHaveProperty("message");
expect(new BlorkError()).toHaveProperty("reason");
expect(new BlorkError()).not.toHaveProperty("value");
});
test("Return correct error with message only", () => {
expect(new BlorkError("Message")).toHaveProperty("message", "Message");
expect(new BlorkError("Message")).toHaveProperty("prefix", "");
expect(new BlorkError("Message")).toHaveProperty("reason", "Message");
expect(new BlorkError("Message")).not.toHaveProperty("value");
});
test("Return correct error with message and value", () => {
expect(new BlorkError("Message", 123)).toHaveProperty("message", "Message (received 123)");
expect(new BlorkError("Message", 123)).toHaveProperty("prefix", "");
expect(new BlorkError("Message", 123)).toHaveProperty("reason", "Message");
expect(new BlorkError("Message", 123)).toHaveProperty("value", 123);
});
test("Return correct error with message, value, and prefix", () => {
expect(new BlorkError("Message", 123, "Prefix")).toHaveProperty("message", "Prefix: Message (received 123)");
expect(new BlorkError("Message", 123, "Prefix")).toHaveProperty("prefix", "Prefix");
expect(new BlorkError("Message", 123, "Prefix")).toHaveProperty("reason", "Message");
expect(new BlorkError("Message", 123, "Prefix")).toHaveProperty("value", 123);
});
});
33 changes: 33 additions & 0 deletions test/errors/ValueError.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const ValueError = require("../../lib/errors/ValueError");

// Tests.
describe("ValueError()", () => {
test("Return correct error with default message", () => {
expect(new ValueError()).toHaveProperty("name", "ValueError");
expect(new ValueError()).toHaveProperty("message", "Invalid value");
expect(new ValueError()).toHaveProperty("prefix", "");
expect(new ValueError()).toHaveProperty("reason", "Invalid value");
expect(new ValueError()).not.toHaveProperty("value");
});
test("Return correct error with message only", () => {
expect(new ValueError("Message")).toHaveProperty("name", "ValueError");
expect(new ValueError("Message")).toHaveProperty("message", "Message");
expect(new ValueError("Message")).toHaveProperty("prefix", "");
expect(new ValueError("Message")).toHaveProperty("reason", "Message");
expect(new ValueError("Message")).not.toHaveProperty("value");
});
test("Return correct error with message and value", () => {
expect(new ValueError("Message", 123)).toHaveProperty("name", "ValueError");
expect(new ValueError("Message", 123)).toHaveProperty("message", "Message (received 123)");
expect(new ValueError("Message", 123)).toHaveProperty("prefix", "");
expect(new ValueError("Message", 123)).toHaveProperty("reason", "Message");
expect(new ValueError("Message", 123)).toHaveProperty("value", 123);
});
test("Return correct error with message, value, and prefix", () => {
expect(new ValueError("Message", 123, "Prefix")).toHaveProperty("name", "ValueError");
expect(new ValueError("Message", 123, "Prefix")).toHaveProperty("message", "Prefix: Message (received 123)");
expect(new ValueError("Message", 123, "Prefix")).toHaveProperty("prefix", "Prefix");
expect(new ValueError("Message", 123, "Prefix")).toHaveProperty("reason", "Message");
expect(new ValueError("Message", 123, "Prefix")).toHaveProperty("value", 123);
});
});

0 comments on commit 988c34a

Please sign in to comment.