Check a batch of records, and report every problem without stopping.
What to build
A validator that uses its own error class, and a summary at the end.
Requirements
- Each line should be JSON with a
nameand anage. - If the line is not valid JSON, print
bad json. - If
nameis not a non-empty string, printinvalid name. That includes JSON which is not an object. - If the name is fine but
ageis not a number from 0 to 150, printinvalid age. - Otherwise, print
ok NAME. - Finally, print
summary: X ok, Y invalid, Z bad json.
Input
Several lines of text.
Output
One line per input line, then the summary.
Constraints
There are from 1 to 50 lines.
Example
Input:
{"name":"Mitu","age":21}
{"name":"","age":3}
not json
Output:
ok Mitu
invalid name
bad json
summary: 1 ok, 1 invalid, 1 bad json
Why it works
A custom error class carries the name of the bad field up to the code that does the reporting. The catch block uses instanceof to respond correctly to each kind of failure, and re-throws anything it did not expect.
Examples
Example 1 · Input
{"name":"Mitu","age":21}
{"name":"","age":3}
not json
Expected output
ok Mitu invalid name bad json summary: 1 ok, 1 invalid, 1 bad json
Example 2 · Input
{"name":"A","age":0}
Expected output
ok A summary: 1 ok, 0 invalid, 0 bad json
Hints
Hint 1
class ValidationError extends Error can store a field name in this.field.
Hint 2
record?.name protects you when the JSON is null.
Hint 3
Parse first, then validate. Use instanceof to tell your error from a SyntaxError.
Solution
Show one correct solution (try it yourself first)
class ValidationError extends Error {
constructor(field) {
super(`invalid ${field}`);
this.name = "ValidationError";
this.field = field;
}
}
function validate(record) {
if (typeof record?.name !== "string" || record.name === "") {
throw new ValidationError("name");
}
if (typeof record.age !== "number" || record.age < 0 || record.age > 150) {
throw new ValidationError("age");
}
}
const totals = { ok: 0, invalid: 0, bad: 0 };
let line = prompt();
while (line !== null) {
try {
const record = JSON.parse(line);
validate(record);
totals.ok++;
console.log(`ok ${record.name}`);
} catch (err) {
if (err instanceof ValidationError) {
totals.invalid++;
console.log(err.message);
} else if (err instanceof SyntaxError) {
totals.bad++;
console.log("bad json");
} else {
throw err;
}
}
line = prompt();
}
console.log(`summary: ${totals.ok} ok, ${totals.invalid} invalid, ${totals.bad} bad json`);