SKU // 107

JavaScript Errors

Errors will happen, every time you write code. Some are typing mistakes, some come from bad input, and some from things you never expected. This lesson introduces the kinds of errors JavaScript reports, how to read an error message, and a first look at try...catch, the tool for handling errors instead of crashing.

// An Error Stops the Script

When JavaScript hits an error it cannot handle, it throws the error, stops, and reports it in the console. Nothing after that line runs:

console.log("Before");
console.log(price * 2);     // price was never declared
console.log("After");
Before ReferenceError: price is not defined

"After" never prints. In the browser console the error shows in red as Uncaught ReferenceError: price is not defined. "Uncaught" means nothing handled it.

// Reading an Error Message

Every error message has the same parts. Learn to read all of them before you start changing code:

Part Example Tells you
TypeReferenceErrorWhat kind of problem it is
Messageprice is not definedThe specific problem, often naming the culprit
Locationscript.js:2The file and line number (click it in the console to jump there)

// try...catch: A First Look

Put code that might fail in a try block. If an error is thrown, JavaScript jumps to the catch block instead of stopping, and hands you the error object (here named err). The two always come as a pair:

let x = 5;
try {
  x = y + 1;               // y does not exist
} catch (err) {
  console.log(err.name);
  console.log(err.message);
}
console.log("The program keeps going");
ReferenceError y is not defined The program keeps going

Every error object has a name (its type) and a message. JS Error Statements covers try, catch, finally, and throw in full; the rest of this lesson uses try...catch only to show you each type of error.

// ReferenceError

A ReferenceError means you used a name that does not exist (usually a typo or a missing let/const), or used a let/const variable before its line (the temporal dead zone from JS Hoisting):

try {
  let fname = foo;
} catch (err) {
  console.log(err.name + ": " + err.message);
}

try {
  let x = y;
  let y = 5;
} catch (err) {
  console.log(err.name + ": " + err.message);
}
ReferenceError: foo is not defined ReferenceError: Cannot access 'y' before initialization

// TypeError

A TypeError means the value exists, but you used it in a way its type does not allow: calling something that is not a function, using a string method on a number, reading a property of undefined or null, or changing a const:

const tests = [
  () => { let anna = 5; anna(5); },
  () => { let num = 1; num.toUpperCase(); },
  () => { let user; user.name; },
  () => { const total = 1; total = 2; }
];

for (const test of tests) {
  try {
    test();
  } catch (err) {
    console.log(err.name + ": " + err.message);
  }
}
TypeError: anna is not a function TypeError: num.toUpperCase is not a function TypeError: Cannot read properties of undefined (reading 'name') TypeError: Assignment to constant variable.

The third one is the most common error in all of JavaScript. JS Debugging shows how to track down which value was undefined.

// RangeError

A RangeError means a number is outside the range a method accepts:

const tests = [
  () => new Array(-1),
  () => (1).toPrecision(500),
  () => "abc".repeat(-1),
  () => { function forever() { return forever(); } forever(); }
];

for (const test of tests) {
  try {
    test();
  } catch (err) {
    console.log(err.name + ": " + err.message);
  }
}
RangeError: Invalid array length RangeError: toPrecision() argument must be between 1 and 100 RangeError: Invalid count value: -1 RangeError: Maximum call stack size exceeded

The last one comes from a function that calls itself forever. Each call waits for the next, until JavaScript runs out of room to keep track of them.

// URIError

A URI (Uniform Resource Identifier) is a web address. encodeURIComponent makes text safe to put in a URL, and decodeURIComponent / decodeURI turn it back. A URIError means the text to decode is broken:

console.log(encodeURIComponent("Tom & Jerry"));
console.log(decodeURIComponent("Tom%20%26%20Jerry"));

try {
  decodeURI("%%%");        // % must be followed by two hex digits
} catch (err) {
  console.log(err.name + ": " + err.message);
}
Tom%20%26%20Jerry Tom & Jerry URIError: URI malformed

// SyntaxError

A SyntaxError means the code breaks JavaScript's grammar rules. These are different from all the others: JavaScript reads (parses) the whole script before running any of it, so a syntax error anywhere means none of that script runs, not even the lines above it.

Code Chrome says Problem
let fName = "John);Invalid or unexpected tokenThe string is never closed
Math.round(4.6;missing ) after argument listA ( with no matching )
if (x == 5 {Unexpected token '{'The ) is missing before {
if (ok) {Unexpected end of inputA { with no matching }
let 1st = "a";Invalid or unexpected tokenNames cannot start with a digit

Because the script never starts, a try...catch in the same script cannot catch its own syntax error. But text that is parsed while the program runs, like JSON, throws a SyntaxError you can catch:

try {
  JSON.parse("{bad json}");
} catch (err) {
  console.log(err.name);
  console.log(err instanceof SyntaxError);
}
SyntaxError true
W3Schools errors on its Errors page
  • Its SyntaxError table gives the messages as "Invalid or unexpected token )" and "Missing ) after argument list." Chrome says Invalid or unexpected token (no parenthesis) and missing ) after argument list (lowercase).
  • Its "not catchable" example reads err.description. description is a non-standard property that only old Microsoft browsers had (see JS Error Object).
  • It lists EvalError as a type to know. It is a leftover: modern JavaScript does not throw it for eval() problems, so you will almost never see one.

// Silent Errors

Some mistakes do not throw anything. 1 / 0 quietly gives Infinity and "abc" * 5 gives NaN, and the program keeps running with wrong data. Those are the subject of the next lesson, JS Silent Errors.

// Summary

Error Means Common cause
ReferenceErrorThat name does not exist (yet)Typo, missing let/const, used before declared
TypeErrorWrong kind of value for that operationundefined/null property, not a function, const reassigned
RangeErrorA number out of the allowed rangeBad length or digit count, endless recursion
URIErrorBroken URL encodingA stray % when decoding
SyntaxErrorCode (or JSON) breaks grammar rulesMissing ) } or quote, bad JSON

// Quick Check

What does this log?

try {
  null.length;
} catch (e) {
  console.log(e.name);
}
Show answer
TypeError. null has no properties, so reading .length is using a value in a way its type does not allow.

Which error does let 1st = "a"; cause?

  1. ReferenceError
  2. TypeError
  3. SyntaxError
  4. RangeError
Show answer
C. A variable name cannot start with a digit, so the code breaks the grammar rules: SyntaxError: Invalid or unexpected token.

A script starts with console.log("Before"); and has a syntax error on line 20. Why does "Before" never print?

Show answer
JavaScript parses the whole script before running any of it. The syntax error is found during parsing, so the script never starts, and line 1 never runs.

// Try It

  1. Click Open Playground. Cause a ReferenceError, a TypeError, and a RangeError on purpose, and catch each one
  2. Log err.name and err.message for each error you caught
  3. Break a line with a missing ) and read the SyntaxError in the Console
  4. Use try...catch around JSON.parse to handle bad JSON without crashing
// Video Walkthroughs
Last updated: Oct 10, 2026, 1:49 AM ET