Skip to content
Theory · Errors · lesson 5 of 10

Error types

Back to the notes from the chain of tasks. One note says "the table is empty", another "there is no table at all". Whoever catches a note wants to see at once what happened. So a note has a heading, and under it the detailed text.

One catch block catches any error, but errors have different causes. The function userAge reads an age from JSON text and can break in two ways:

JavaScript
function userAge(text) {
    try {
        const data = JSON.parse(text);
        return data.user.age;
    } catch (e) {
        return e.name;
    }
}

console.log(userAge('{"user":{"age":30}}')); // 30
console.log(userAge("{ bad")); // SyntaxError
console.log(userAge("{}")); // TypeError

Let's go through the three calls:

  1. The text '{"user":{"age":30}}' was parsed without errors, and the function returned 30.
  2. On the wrong text JSON.parse threw a SyntaxError.
  3. The object {} has no user property, so reading data.user.age threw a TypeError.

The name property of the caught error tells what exactly happened: the text itself is broken, or data is missing in it.

name and message

Every error object has two properties:

  • name is the kind of error, such as "TypeError"; it is the note's heading;
  • message is its text: for an error you created yourself, the string passed to new Error(…).

When nobody catches an error, Node prints the line TypeError: …: it is name, a colon and message. Node and browsers also add a stack property — a string listing the function calls that led to the error.

Interviewers like to ask this: "What properties does an Error object have?" The answer: name and message, and Node and browsers also add stack.

Built-in kinds

Most often JavaScript itself throws errors of four built-in kinds. Let's go through each.

TypeError

The action does not fit the value. For example:

  • reading a property of undefined;
  • calling something that is not a function;
  • assigning to a constant.

RangeError

A value outside the allowed limits, such as "ab".repeat(-1). In Node and Chrome, recursion that goes too deep throws it too.

ReferenceError

A name that does not exist in the program, such as a typo in a variable name.

SyntaxError

Wrong text for JSON.parse. A syntax error in the file itself cannot be caught: such a file does not run at all.

Inheriting from Error

Each of these kinds is a class that inherits from Error: the same inheritance as the classes with extends from the previous theme. Each sets its own name. You can throw such an error yourself too: throw new RangeError("age is out of range").

JavaScript
const e = new RangeError("age is out of range");
console.log(e.name); // RangeError
console.log(e.message); // age is out of range
console.log(e instanceof RangeError, e instanceof Error); // true true
console.log(e instanceof TypeError); // false

Let's go line by line:

  1. new RangeError(…) creates an error of the kind RangeError with our text.
  2. e.name holds the kind of error: RangeError.
  3. e.message holds the text passed in parentheses.
  4. Both instanceof checks on the fourth line give true: a RangeError is an Error too.
  5. e instanceof TypeError gives false: it is a different kind.

The check instanceof Error is true for any of these kinds, while instanceof RangeError is true for one kind only. One catch catches them all, and inside it the errors are told apart with instanceof or by e.name.

Here the heading picture stops working. One person writes both the heading and the text of a note. For an error, its class sets the kind, while whoever creates it passes the text.

Common mistake

The general check is placed before the specific one:

JavaScript
function describe(e) {
    if (e instanceof Error) {
        return "unknown error";
    } else if (e instanceof SyntaxError) { // ✗
        return "bad JSON";
    }
}

There is no error message, but the second branch never runs. A SyntaxError is an Error too, so describe(new SyntaxError("x")) returns "unknown error". Checks for single kinds go first, and instanceof Error goes last.

Key points

  • An error object has name, the kind of error, and message, its text; Node and browsers add stack.
  • TypeError, RangeError, ReferenceError and SyntaxError inherit from Error and set their own name.
  • instanceof Error is true for any kind, so specific checks go before the general one.

Subscribe to take the course

The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.

Sign in another way