Introduction to errors in Node.js
Tags: node, javascript
Published: 2021-08-04 22:38:45

---
title: Introduction to errors in Node.js
published: true
date: 2021-07-28 00:00:00 UTC
tags: node, javascript
canonical_url: https://www.mariokandut.com/introduction-to-errors-in-node-js/
---

Building robust Node.js applications requires dealing with errors in proper way. Error handling in Node.js is an opinionated topic. This is the first article of a series. It aims to give an overview of different kind of errors in Node.js and the creation and throwing of errors.

Handling Errors in Node.js:

- Overview of errors in Node.js (this article)
- Handling errors in Node.js (future)

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#what-kinds-of-errors-exist-in-nodejs)What kinds of errors exist in Node.js?

There are basically two groups:

- Operational Errors
- Developer Errors

**Operational Errors** are errors that happen while a program is working on a task, like a network failure. Handling of operational errors **should be covered by applying an appropriate scenario strategy**. In case of a network error, a strategy would be to retry the network operation.

Operation errors are:

- failed to connect to server
- failed to resolve hostname
- invalid user input
- request timeout
- server returned a 500 response
- system is out of memory
- etc.

**Developer Errors** are mistakes of developers, for example invalid input. In these cases the application should not attempt to continue running and should crash with a helpful description so that the developer can fix this issue.

Developer Errors are:

- tried to read property of `undefined`
- called an asynchronous function without a callback
- passed a `string` where an object was expected
- passed an object where a property is missing but required
- etc.

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#throwing-errors)Throwing Errors

Typically, an error is dealt with by using the `throw` keyword to throw an exception. The `throw` statement throws a user-defined exception and execution of the current function will stop. Statements after `throw` won't be executed, and the first `catch` block will receive the error. If no catch block exists in the function context, the program will terminate.

For example:

```
function divideByTwo(amount) {
  if (typeof amount !== 'number')
    throw new Error('amount must be a number');
  return amount / 2;
}
```

When `divideByTwo` is called with an invalid input, a string instead of number, the application will crash, and the **stack trace is printed in the console**. This **stack trace comes from the error object** which was created after using the `throw` keyword. The Error constructor is native to JavaScript, takes a string as the Error message and auto-generates the stack trace when created.

It is recommended to throw an **Error Object** , but theoretically any value can be thrown. The stack trace will be lost in that case.

```
function divideByTwo(amount) {
  if (typeof amount !== 'number') throw 'amount must be a number'; // NOT RECOMMENDED
  return amount / 2;
}
```

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#native-error-constructors)Native Error Constructors

To create an error, call `new Error('message')` and pass a string value as a message.

```
new Error('this is a error message');
```

There are six other native error constructors that inherit from the base `Error` constructor in JavaScript:

- EvalError
- SyntaxError
- RangeError
- ReferenceError
- TypeError
- URIError

A `ReferenceError` will be automatically thrown, when attempting to refer to a non-existing reference. This `node -p 'thisReference'` will throw a `ReferenceError` since the reference does not exist.

An error object can also have its instance verified, like `node -p "const err = new SyntaxError(); err instanceof SyntaxError` will return true. This `node -p "const err = new SyntaxError(); err instanceof Error` will also be valid, since any native error constructor inherits from `Error`.

Native errors objects also have a `name` property, which contains the name of the error that created it.`node -p "const err = new RangeError(); console.log('error is: ', err.name);"`

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#custom-errors)Custom Errors

The native errors are a rudimentary set of errors that can't replicate all errors that can occur in an application. For that we have custom errors. There are several ways of communicating various errors, the most common two are **subclassing native error constructors** and using the `code` property.

Let's look at an example to see how a custom error with the `code` property looks like:

```
function divideByTwo(amount) {
  if (typeof amount !== 'number')
    throw new TypeError('amount must be a number');
  if (amount <= 0)
    throw new RangeError('amount must be greater than zero');
  if (amount % 2) {
    const err = Error('amount must be even');
    err.code = 'ERR_MUST_BE_EVEN';
    throw err;
  }
  return amount / 2;
}
```

Now run the function with `divideByTwo(3)` in the `REPL` or create a file and execute the function add the end. The outcome will be something like this:

```
# ... filepath

throw err;
^

Error: amount must be even
# ... stack trace
```

The error can be identified by the `code` value that was added and then handled accordingly. The code API in Node.js uses a similar approach to create native errors. For a list of possible error codes see in the official docs - [Node.js v16.5 - List of Error Codes](https://nodejs.org/api/errors.html#errors_node_js_error_codes).

Another way to create custom errors is to inherit ourselves from the `Error` object and create a custom error instance. Let's create an `OddError` constructor:

```
class OddError extends Error {
  constructor(varName = '') {
    super(varName + ' must be even');
  }
  get name() {
    return 'OddError';
  }
}
```

Now we'll update the `divideByTwo()` to use `OddError`. The custom error has to be in the same file or imported:

```
function divideByTwo(amount) {
  if (typeof amount !== 'number')
    throw new TypeError('amount must be a number');
  if (amount <= 0)
    throw new RangeError('amount must be greater than zero');
  if (amount % 2) throw new OddError('amount');
  return amount / 2;
}
```

The output will be:

```
# ... file path
    if (amount % 2) throw new OddError('amount');
                    ^

OddError: amount must be even
# ... stack trace
```

The strategy to use a custom error constructor and adding a code property are not mutually exclusive, so both can be used at the same time. Let's update the `OddError` example:

```
class OddError extends Error {
  constructor(varName = '') {
    super(varName + ' must be even');
    this.code = 'ERR_MUST_BE_EVEN';
  }
  get name() {
    return `OddError [${this.code}]`;
  }
}
```

The output after execution will be:

```
# ... file path
if (amount % 2) throw new OddError('amount');
                    ^
OddError [ERR_MUST_BE_EVEN]: amount must be even
# ... stack trace
```

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#tldr)TL;DR

- Errors in Node.js are handled through exceptions.
- An error can be created with using the constructor `new Error('error message')` and thrown using the `throw` keyword.
- Always throw `Error` object instead of value to keep stack trace.
- There are six native error constructors which inherit from `Error`.
- Custom errors can be created with the `code property` and/or using a constructor with inheriting from the `Error` object.

Thanks for reading and if you have any **questions** , use the **comment** function or **send me a message** **[@mariokandut](https://www.twitter.com/mariokandut)**.

If you want to know more about **[Node](https://www.mariokandut.com/tags/node)**, have a look at these [Node Tutorials](https://www.mariokandut.com/tags/node).

**References (and Big thanks):**

[JSNAD](https://trainingportal.linuxfoundation.org/learn/course/nodejs-application-development-lfw211/handling-errors/handling-errors?page=3),[MDN Errors](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error),[MDN throw](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw),[Node.js Error Codes](https://nodejs.org/api/errors.html#errors_node_js_error_codes),[Joyent](https://www.joyent.com/node-js/production/design/errors)