Skip to main content

Types of errors in JavaScript

In JavaScript every error inherits from the base Error class, and there are seven built in specialised types: ReferenceError, TypeError, RangeError, SyntaxError, URIError, EvalError and AggregateError. Each of them signals its own class of problem, and on top of that you can always create your own error type by extending Error.

Theory

TL;DR

  • Error is the base class with the name, message and stack properties.
  • ReferenceError, TypeError and RangeError are the three most common runtime errors.
  • SyntaxError happens at parse time, so an ordinary try...catch cannot catch it.
  • URIError concerns the URI encoding functions, EvalError is practically unused.
  • AggregateError bundles several errors at once, for example in Promise.any().
  • You create your own error type with class MyError extends Error.

Quick example

javascript
try { null.toString(); } catch (e) { console.log(e.name); // TypeError console.log(e.message); // Cannot read properties of null }

Error, the base error class

This is the universal type that all other errors inherit from. If you do not know which error type fits, you can simply use Error.

javascript
throw new Error("Something went wrong");

Properties of an error object:

  • name, the name of the error ("Error")
  • message, the description
  • stack, the stack trace, showing where exactly the error happened

Runtime errors: ReferenceError, TypeError, RangeError

ReferenceError, a reference error. It occurs when the code touches a variable that does not exist, or a binding that is not available in the current scope.

javascript
console.log(x); // ReferenceError: x is not defined

It can also arise from incorrect use of this.

TypeError, a type error. It happens when an operation is applied to a value of an unsuitable type, or when you try to call something that is not a function.

javascript
let n = null; console.log(n.toString()); // TypeError: Cannot read properties of null
javascript
let func = 123; func(); // TypeError: func is not a function

RangeError, going outside the allowed limits. It occurs when the value passed in is outside the acceptable range.

javascript
new Array(-5); // RangeError: Invalid array length
javascript
(123.456).toFixed(200); // RangeError: toFixed() digits argument must be between 0 and 100

SyntaxError, URIError, EvalError and AggregateError

SyntaxError, a syntax error. An error caused by breaking JavaScript syntax. The engine cannot parse the code, so the program does not even start.

javascript
eval("if (true { console.log('hi'); }"); // SyntaxError: Unexpected token '{'

Such errors cannot be caught with try...catch, because they happen before execution begins. The exception is code that is parsed separately and later, as in the eval example above or inside new Function(...).

URIError, an error in the URI functions. It happens when encodeURI(), decodeURI(), encodeURIComponent() or decodeURIComponent() receive malformed data.

javascript
decodeURIComponent("%"); // URIError: URI malformed

EvalError, an error while using eval(). Rare in modern implementations. It was originally used when eval() was applied incorrectly.

javascript
throw new EvalError("Incorrect use of eval()");

AggregateError, a set of errors. It arises when a single operation returns several errors at once, for example with Promise.any().

javascript
Promise.any([ Promise.reject(new Error("Error 1")), Promise.reject(new Error("Error 2")), ]).catch(e => console.log(e.errors));

Output:

text
[Error: Error 1, Error: Error 2]

Custom errors

You can create your own error classes by extending Error:

javascript
class ValidationError extends Error { constructor(message) { super(message); this.name = "ValidationError"; } } throw new ValidationError("Invalid email");

Output:

text
ValidationError: Invalid email

This approach lets you tell domain errors from technical ones right inside catch, with if (e instanceof ValidationError).

Summary table

Error typeWhen it occursExample
ErrorBase class for all errorsthrow new Error("Failure")
ReferenceErrorThe variable is not definedconsole.log(x)
TypeErrorWrong value typenull.toString()
RangeErrorValue outside the allowed rangenew Array(-1)
SyntaxErrorA syntax erroreval("if (true {")
URIErrorAn error encoding or decoding a URIdecodeURI("%")
EvalErrorAn eval() error (almost never used)throw new EvalError()
AggregateErrorSeveral errors at oncePromise.any([...])

Common mistakes

  • Expecting try...catch to catch a SyntaxError in your own file. That code will not run at all, because parsing happens before execution.
  • Catching everything with one catch (e) and never looking at e.name. Without a type check you handle a validation failure exactly like a network outage.
  • Forgetting super(message) in a custom error class. Then message comes out empty and the stack is incomplete.
  • Confusing ReferenceError and TypeError. The variable does not exist at all, that is a ReferenceError; the variable exists but its value is null or undefined, that is already a TypeError.
  • Relying on EvalError. Modern engines hardly ever throw it, so do not build logic around it.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.