JavaScript has several distinct built-in Error subtypes — TypeError, ReferenceError, RangeError, SyntaxError, and more — each signaling a different category of mistake, and recognizing them quickly is a core debugging skill.
1Built-in Error Types | JavaScript Tutorial - In-Depth Guide Part 1
TypeError is thrown when a value is used in a way that's incompatible with its type — calling something that isn't a function, or accessing a property on null/undefined.
const notAFunction = 5;
notAFunction(); // TypeError: notAFunction is not a functionTypeError
2Built-in Error Types | JavaScript Tutorial - In-Depth Guide Part 2
ReferenceError signals that code tried to use a variable that doesn't exist in any accessible scope, or accessed a let/const binding before its declaration (the Temporal Dead Zone).
console.log(undeclaredVariable); // ReferenceError: undeclaredVariable is not definedReferenceError
3Built-in Error Types | JavaScript Tutorial - In-Depth Guide Part 3
RangeError is thrown when a value is outside the set of allowed values for an operation, like an invalid array length or a number formatting precision out of bounds.
new Array(-1); // RangeError: Invalid array length
(5).toFixed(200); // RangeError: toFixed() digits argument must be...RangeError
4Built-in Error Types | JavaScript Tutorial - In-Depth Guide Part 4
SyntaxError is thrown when code is malformed and cannot even be parsed — this typically happens at parse time (or when parsing dynamic code like JSON.parse or eval).
JSON.parse('{invalid json}'); // SyntaxError: Unexpected token i in JSONSyntaxError
5Built-in Error Types | JavaScript Tutorial - In-Depth Guide Part 5
Check error.name (a string) or use instanceof against the global error constructors to reliably distinguish which built-in error type you're handling.
try {
riskyOperation();
} catch (err) {
if (err instanceof TypeError) handleTypeIssue(err);
else if (err instanceof RangeError) handleRangeIssue(err);
else handleGeneric(err);
}Distinguishing Error Types
6Step-by-Step Breakdown
TypeError is thrown when a value is used in a way that's incompatible with its type — calling something that isn't a function, or accessing a property on null/undefined.
ReferenceError signals that code tried to use a variable that doesn't exist in any accessible scope, or accessed a let/const binding before its declaration (the Temporal Dead Zone).
Checkpoint: Which error type signals that a variable name could not be resolved in any accessible scope?
- →ReferenceError
- →TypeError
RangeError is thrown when a value is outside the set of allowed values for an operation, like an invalid array length or a number formatting precision out of bounds.
SyntaxError is thrown when code is malformed and cannot even be parsed — this typically happens at parse time (or when parsing dynamic code like JSON.parse or eval).
Checkpoint: Can a SyntaxError from JSON.parse() be caught with a normal try/catch, just like other runtime errors?
- →Yes, it behaves like any other thrown error at runtime
- →No, it always crashes the entire script immediately
Check error.name (a string) or use instanceof against the global error constructors to reliably distinguish which built-in error type you're handling.
Next, we'll explore 'Global Error Handling'.
Level Up 🚀
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Translate Technical Error Types into Plain-Language Accessible Messages
Raw error type names like 'TypeError' mean nothing to end users; when surfacing an error to the UI, translate it into a clear, non-technical message appropriate for an ARIA live region or alert, reserving the technical error type for developer-facing logs.
SEO Implications
- 1
No Direct SEO Effect
Built-in error types are a debugging/diagnostic concept with no direct bearing on search visibility.
Best Practices
Read the Specific Error Type Before Debugging the Message Text
The error's constructor name (TypeError vs ReferenceError vs RangeError) immediately narrows down the category of mistake, often faster than parsing the full message.
Use instanceof to Branch on Built-in Error Types When Handling Errors Programmatically
It correctly respects the prototype chain and is more robust than string-matching against error.message, which can vary slightly between engines.
Frequent Bugs
Misreading a 'Cannot read properties of undefined' TypeError as a ReferenceError, leading to debugging the wrong part of the code (assuming a variable is undeclared rather than an object being unexpectedly null/undefined).
Recognize this specific message pattern as a TypeError caused by property access on null/undefined, and trace back to why that particular object turned out to be missing.
Catching JSON.parse() errors generically without checking that they are specifically a SyntaxError, potentially masking other unrelated bugs in the same try block.
Scope try/catch blocks narrowly around just the JSON.parse() call, and optionally check `err instanceof SyntaxError` if you need to react specifically to malformed JSON.
Real-World Examples
Providing a Specific Error Message for Malformed Config Files
An app loaded a JSON configuration file and needed to show a clear, actionable message specifically when the file was malformed, as opposed to other kinds of loading failures.
try {
const config = JSON.parse(fileContents);
} catch (err) {
if (err instanceof SyntaxError) {
throw new Error('Config file contains invalid JSON: ' + err.message);
}
throw err;
}