Error Types
The Six Diagnostic Codes of JavaScript
LinkedIn Hook
You wrap a block in
try/catchto catch a missing semicolon. It does not work. The script never even runs. Why?Because JavaScript has two worlds: parse time and runtime. Most
SyntaxErrors happen before a single line of your code executes, which meanstry/catchcannot possibly catch them — the catch was never even parsed. Buteval()andJSON.parse()throwSyntaxErrorat runtime, and those you CAN catch.This is one of six built-in error types, each with a precise meaning.
TypeError— wrong type.ReferenceError— undeclared name.RangeError— out of bounds (hello, infinite recursion).URIError— malformed%encoding.EvalError— legacy, effectively dead.In this lesson you will learn every built-in type, what triggers each one, and exactly which ones you can catch.
Read the full lesson -> [link]
#JavaScript #InterviewPrep #ErrorHandling #JSInternals #Frontend #NodeJS #CodingInterview #WebDevelopment
What You'll Learn
- The six built-in error types, what triggers each one, and when they fire
- Why most
SyntaxErrors escapetry/catch— and the exact two cases where they do not - How every built-in type inherits from
Error, and how to defend against the two most common ones
Diagnostic Codes at a Mechanic Shop
JavaScript has seven built-in error types. Think of them like diagnostic codes at a mechanic shop — each one tells you a specific category of what went wrong, which helps you fix the problem faster.
Error Types Reference Table
| Error Type | When It Occurs | Catchable with try/catch? |
|---|---|---|
TypeError | Operation on wrong type (e.g., calling non-function) | Yes |
ReferenceError | Using a variable that doesn't exist | Yes |
SyntaxError | Invalid JavaScript syntax | Usually NO (parse-time) |
RangeError | Value outside valid range | Yes |
URIError | Malformed URI encoding/decoding | Yes |
EvalError | Issues with eval() (legacy, rarely seen) | Yes |
TypeError — The Most Common One
Occurs when a value is not the expected type for an operation.
// Calling a non-function
const x = 42;
x(); // TypeError: x is not a function
// Accessing property of null/undefined
const obj = null;
obj.name; // TypeError: Cannot read properties of null
// Calling method on wrong type
const num = 123;
num.toUpperCase(); // TypeError: num.toUpperCase is not a function
// Assigning to a constant
const PI = 3.14;
PI = 3; // TypeError: Assignment to constant variable
// Calling constructor without new
function Person(name) {
"use strict";
this.name = name;
}
Person("Rakibul"); // TypeError in strict mode
// How to defend against TypeError
function safePropAccess(obj, prop) {
// Optional chaining (ES2020)
return obj?.prop;
}
// Nullish coalescing for defaults
const name = user?.name ?? "Anonymous";
ReferenceError — Using Undeclared Variables
Occurs when you try to use a variable that hasn't been declared in the accessible scope.
// Variable doesn't exist
console.log(myVar); // ReferenceError: myVar is not defined
// Accessing before declaration (TDZ — Temporal Dead Zone)
console.log(x); // ReferenceError: Cannot access 'x' before initialization
let x = 10;
// Typo in variable name
const userName = "Rakibul";
console.log(usrName); // ReferenceError: usrName is not defined
// How to safely check if something exists
if (typeof someVar !== "undefined") {
// Safe to use someVar
}
// typeof never throws ReferenceError
console.log(typeof nonExistent); // "undefined" — no error!
SyntaxError — Usually NOT Catchable
SyntaxError typically occurs at parse time, before any code executes. This means try/catch can't catch it — the code never gets to run.
// PARSE-TIME — Cannot be caught
// This entire script will fail to load:
// const x = ; // SyntaxError: Unexpected token ';'
// The try/catch below NEVER EXECUTES because the file
// fails to parse before any code runs:
try {
const x = ; // SyntaxError at parse time — try/catch can't help
} catch (e) {
// This catch NEVER runs
}
// RUNTIME SyntaxError — CAN be caught
// eval() and JSON.parse() throw SyntaxError at runtime
try {
eval("const x = ;"); // SyntaxError thrown at RUNTIME
} catch (e) {
console.log(e.name); // "SyntaxError"
console.log(e.message); // "Unexpected token ';'"
// This catch DOES run because eval parses at runtime
}
try {
JSON.parse("{ invalid }");
} catch (e) {
console.log(e.name); // "SyntaxError"
// Runtime SyntaxError from JSON.parse — catchable!
}
RangeError — Value Out of Bounds
Occurs when a value is outside the allowed range.
// Invalid array length
const arr = new Array(-1); // RangeError: Invalid array length
// Maximum call stack exceeded (infinite recursion)
function forever() {
forever();
}
forever(); // RangeError: Maximum call stack size exceeded
// Number methods with invalid precision
const num = 1.5;
num.toFixed(200); // RangeError: toFixed() digits argument must be between 0 and 100
// Invalid date
const date = new Date("not-a-date");
date.toISOString(); // RangeError: Invalid time value
URIError — Malformed URI
Occurs when URI encoding/decoding functions receive malformed input.
// Invalid URI decoding
try {
decodeURIComponent("%"); // URIError: URI malformed
} catch (e) {
console.log(e.name); // "URIError"
}
try {
decodeURI("%E0%A4%A"); // URIError: URI malformed
} catch (e) {
console.log(e.message); // "URI malformed"
}
// Valid URI operations — no error
encodeURIComponent("hello world"); // "hello%20world"
decodeURIComponent("hello%20world"); // "hello world"
EvalError — Legacy, Rarely Seen
EvalError exists for historical reasons. Modern JavaScript engines don't throw it, but it's still available as a constructor.
// EvalError is never thrown by modern engines
// It exists for backward compatibility
const e = new EvalError("legacy error");
console.log(e instanceof EvalError); // true
console.log(e instanceof Error); // true
// What modern engines throw instead:
// eval("invalid code") throws SyntaxError, not EvalError
All Error Types Inherit from Error
// Every built-in error is an instance of Error
const errors = [
new TypeError("type"),
new ReferenceError("ref"),
new SyntaxError("syntax"),
new RangeError("range"),
new URIError("uri"),
new EvalError("eval"),
];
errors.forEach((e) => {
console.log(e.name, "instanceof Error:", e instanceof Error); // all true
});
Common Mistakes
- Trying to catch a missing bracket or bad syntax with
try/catchin the same file — parse-timeSyntaxErrorkills the file beforetry/catchis even parsed. You only catch runtimeSyntaxError(fromeval,new Function,JSON.parse). - Using
if (someVar)to check whether a variable is declared — that itself throwsReferenceError. Usetypeof someVar !== "undefined", which never throws. - Treating
TypeError: Cannot read properties of undefinedas "a null bug" — optional chaining (?.) + nullish coalescing (??) is almost always the right fix, and strict type checks or schema validation at the boundary prevents it from reaching deep code.
Interview Questions
Q: Name all 6 built-in JavaScript error types.
TypeError,ReferenceError,SyntaxError,RangeError,URIError, andEvalError. All six inherit fromError.EvalErroris legacy — modern engines no longer throw it, but the constructor is kept for backward compatibility.
Q: Why can't you catch most SyntaxErrors with try/catch?
Most SyntaxErrors occur at parse time, before any code executes. The JavaScript engine must parse the entire file before running it. If parsing fails, no code runs — including the try/catch wrapper. However, runtime SyntaxErrors from
eval(),new Function(), orJSON.parse()CAN be caught because they parse code dynamically at runtime.
Q: When CAN a SyntaxError be caught?
Whenever the syntax error happens at runtime rather than at file parse time. The three common triggers are
eval(code),new Function(code), andJSON.parse(text)— each one parses a string at runtime, so if the string is invalid you get a catchableSyntaxError.
Q: What's the difference between TypeError and ReferenceError?
ReferenceErrormeans the variable doesn't exist in scope at all — the engine can't find it.TypeErrormeans the variable exists but you're trying to do something invalid with its value — like callingnull.method()or using a number as a function.
Q: What causes RangeError: Maximum call stack size exceeded?
Infinite recursion — a function that calls itself without a proper base case. Each function call adds a frame to the call stack, and when the stack overflows, JavaScript throws this RangeError. Fix it by ensuring your recursive function has a reachable base case.
Quick Reference — Cheat Sheet
ERROR TYPES — QUICK MAP
TypeError -> wrong type operation (null.prop, x(), const PI=...; PI=3)
ReferenceError -> undeclared name (missing var, TDZ, typo)
SyntaxError -> invalid syntax (parse-time = UNCATCHABLE)
(eval / JSON.parse = catchable)
RangeError -> value out of bounds (new Array(-1), infinite recursion,
toFixed(>100), Invalid Date)
URIError -> malformed URI (decodeURIComponent('%'))
EvalError -> legacy (modern engines don't throw this)
All inherit from Error:
e instanceof Error -> true (for every built-in type)
Defenses:
TypeError -> obj?.prop, value ?? default, schema-validate inputs
ReferenceError -> typeof someVar !== "undefined" (never throws)
SyntaxError -> try/catch around JSON.parse / eval / new Function
Previous: Custom Errors Next: Error Handling in Promises
This is Lesson 10.3 of the JavaScript Interview Prep Course — 14 chapters, 87 lessons.