You will be able to deliberately throw JavaScript Error objects to stop invalid execution and report clear failure reasons.
What it is
An error statement in JavaScript is a deliberate signal that something has gone wrong. The most common form is throw new Error("bad input"). It creates an Error object and raises it. JavaScript can throw any value, but Error objects are preferred because they carry useful debugging information. If no try...catch handles it, the current synchronous execution stops and the runtime reports an uncaught exception.
Mental model: throwing is like pulling an emergency brake. It does not return a value; it transfers control to the nearest matching catch block, or to the runtime if none exists.
Related terms: try, catch, finally, TypeError, RangeError, custom error, stack trace.
Why it matters
- Prevents invalid data from spreading through functions.
- Makes failures explicit instead of producing silent wrong results.
- Provides a message and stack trace for debugging.
- Works well with centralized error handling in
catchblocks. - Helps API boundaries reject bad arguments early.
Syntax or steps
Smallest useful pattern:
if (!condition) {
throw new Error("clear message");
}
- Check for an invalid state or argument.
- Create an
Errorobject with a specific message. - Use
throwto stop normal execution. - Handle it with
try...catchif the caller can recover.
Example
function withdraw(balance, amount) {
if (typeof amount !== "number" || Number.isNaN(amount)) {
throw new TypeError("amount must be a number");
}
if (amount <= 0) {
throw new RangeError("amount must be positive");
}
if (amount > balance) {
throw new Error("insufficient funds");
}
return balance - amount;
}
try {
console.log(withdraw(100, 30));
console.log(withdraw(100, 150));
} catch (error) {
console.log(error.name + ": " + error.message);
}
Part by part:
withdrawvalidates inputs before doing work.TypeErrorandRangeErrorare built-in error types that communicate the kind of problem.throwstops the function immediately.- The
catchblock receives the thrown error and prints itsnameandmessage.
Expected output:
70
Error: insufficient funds
Common mistakes
- Throwing strings like
throw "bad input". Preferthrow new Error("bad input")so you get a stack trace and standard properties. - Using vague messages like
"error". Include what failed and why, such as"email must contain @". - Throwing inside loops without a reason. This can stop execution too early; validate once or collect errors if needed.
- Catching and ignoring errors with an empty
catch. At least log or rethrow if the caller cannot recover.
When to use it
Use throw when continuing would be unsafe or meaningless. Use return values when failure is expected and the caller can handle it as normal data.
| Situation | Use | Why |
|---|---|---|
| Invalid argument that cannot be processed | throw new Error(...) | Stops bad state early. |
| Expected empty result, such as no search match | Return null or empty array | Not exceptional; caller can continue. |
| Recoverable network failure | Throw or return result object depending on API design | Choose one clear contract. |
| Debugging only | console.error | Does not stop execution. |
Practice
Guided exercise: Write a function parseAge(value) that throws a TypeError if value is not a number, throws a RangeError if the number is negative, and returns the number otherwise.
function parseAge(value) {
if (typeof value !== "number") {
throw new TypeError("age must be a number");
}
if (value < 0) {
throw new RangeError("age cannot be negative");
}
return value;
}
Challenge: Call parseAge("25") inside a try...catch and print the error message. Expected output: age must be a number.
Quick check
Question: What happens when you use throw new Error("bad input") inside a function with no surrounding try...catch?
Answer: The function stops, the error propagates upward, and if nothing catches it, the JavaScript runtime reports an uncaught exception.
Summary
Throwing deliberate errors turns silent failures into clear, debuggable stops. Use throw new Error(...) for invalid states, and handle expected failures with return values or try...catch depending on your program's contract.