-
Section 1: Getting Started
-
Section 2: Core Syntax and Types
-
Section 3: Strings and Numbers in Depth
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Objects and Arrays
-
Section 7: Maps, Sets, and Symbols
-
Section 8: Asynchronous JavaScript
-
Section 9: Object-Oriented and Prototypes
-
Section 10: The DOM
-
Section 11: Browser APIs
-
Section 12: Modern JavaScript (ES2015-ES2025)
-
Section 13: Functional Programming Patterns
-
Section 14: Error Handling and Debugging
-
Section 15: Testing
-
Section 16: Accessibility for JavaScript Developers
-
Section 17: Internationalization and Localization
-
Section 18: Performance
-
Section 19: Node.js Fundamentals
-
Section 20: Regular Expressions
-
Section 21: Design Patterns in JavaScript
-
Section 22: Security Basics
-
Section 23: Data Structures and Algorithms in JavaScript
-
Section 24: Practical Projects
-
Section 25: More Advanced Async Patterns
-
Section 26: More Object and Class Practice
-
Section 27: Working with Dates and Internationalization
-
Section 28: Web Components
-
Section 29: More DOM and Browser Practice
-
Section 30: Build Tooling for Vanilla JavaScript
-
Section 31: More Practice Projects
-
Section 32: Interview and Algorithm Practice
-
Section 33: Error Objects (MDN Reference)
-
Section 34: TypedArrays and Binary Data
-
Section 35: Reflection and Metaprogramming (MDN Reference)
-
Section 36: More Global Functions (MDN Reference)
235: The Error Object Hierarchy: TypeError, RangeError, SyntaxError
I've spent a fair amount of my career staring at red text in a Chrome DevTools console. When you're first starting out, an error is just "the thing that stopped my code from working." But as you get deeper into JavaScript, you realize the engine is actually trying to tell you exactly why it failed. It doesn't just throw a generic "Error"; it uses a hierarchy of specific error types.
Let's play around with this. I'm going to try and build a small piece of logic to process a user's birthday, and I'll intentionally break it in different ways to see how JavaScript reacts.
Wait, why won't this even run?
I'll start with something simple. I'm trying to define a configuration object for my date parser, but I'm a bit tired and I'll just "forget" a comma or a closing bracket.
try {
const config = {
format: 'YYYY-MM-DD'
strict: true // Missing comma on the line above!
};
} catch (e) {
console.log(e.name);
console.log(e.message);
}
Actually, wait. If I just run that in a script, the browser won't even execute the `try...catch` block. Why? Because this is a SyntaxError. A SyntaxError happens during the parsing phase, before the code even starts running. The engine looks at the file, sees that it doesn't follow the grammar rules of JavaScript, and just gives up immediately.
If I move this into a JSON.parse() call—which parses a string at runtime—I can actually catch it:
try {
JSON.parse('{"name": "Dev", "age": 30'); // Missing closing brace
} catch (e) {
console.log(e.name); // "SyntaxError"
}
I thought this was a string...
Now, let's assume the code is syntactically correct, but I'm making a mistake with my data types. I've got a variable that I think is a string (maybe it's a username), and I want to make it uppercase.
const username = 12345; // Oops, this came back as a number from the API
try {
console.log(username.toUpperCase());
} catch (e) {
console.log(e.name); // "TypeError"
console.log(e.message); // "username.toUpperCase is not a function"
}
This is the TypeError. It's arguably the most common error you'll encounter. It doesn't mean the "type" is wrong in a static sense (like in TypeScript), but rather that you're trying to perform an operation on a value that doesn't support it. Calling a method that doesn't exist on a specific type—like toUpperCase() on a number—is a classic trigger.
Pushing the boundaries too far
Finally, there's the RangeError. This is a bit more niche. It's not about the type of the value, but the value itself being outside of an allowed range.
I'll try to create an array with an impossible length. JavaScript arrays have a maximum size, but you can also trigger this by passing a negative number to the Array constructor.
try {
const badArray = new Array(-1);
} catch (e) {
console.log(e.name); // "RangeError"
console.log(e.message); // "Invalid array length"
}
Another place I see this often is with toFixed(). If you try to format a number to 200 decimal places, JavaScript will throw a RangeError because the specification only allows a range between 0 and 100.
So, to recap our exploration:
- SyntaxError: "I can't even read this code; it's gibberish."
- TypeError: "I know what you're asking me to do, but this value isn't the right kind of thing to do it with."
- RangeError: "The value is the right type, but it's way too big or way too small."
📋 Practical Task
Building a Robust Input Sanitizer
Create a function called sanitizeUserData(input) that attempts to process a piece of data. Your function should use a try...catch block to handle three specific scenarios and log a custom message based on the type of error encountered:
- If
inputis a string that is not valid JSON, it should trigger aSyntaxError(Hint: useJSON.parse()). - If the function tries to call
.trim()on something that isn't a string, it should trigger aTypeError. - If the function tries to create a
new Array()using a negative number provided in the input, it should trigger aRangeError.
Your catch block should check e.name` and log:
"Syntax issue detected!" for SyntaxError,
"Wrong data type provided!" for TypeError,
and "Value out of bounds!" for RangeError.
There are no comments for now.