By the end of this lesson, you will be able to recognize common JavaScript runtime errors, explain why they happen, and use try/catch to handle failures without crashing your program.
What it is
An error is a signal that JavaScript cannot continue normal execution. A runtime error happens after code has started running, often because a value is not what the code expected. For example, null.foo throws a TypeError because null has no properties. The mental model is simple: JavaScript runs instructions until something fails, then it throws an exception and searches up the call stack for a matching catch block. Related terms include throw, catch, finally, stack trace, and exception.
Why it matters
- It prevents one bad value from stopping an entire application.
- It gives you a place to show a useful message instead of a blank screen.
- It lets you log or report failures for debugging.
- It supports fallback behavior, such as using a default value.
- It helps separate expected failures from unexpected bugs.
Syntax or steps
The smallest useful pattern is a try block around risky code and a catch block to handle the error. A finally block is optional and runs whether or not an error occurs.
try {
// code that might fail
} catch (error) {
// handle or report the error
} finally {
// optional cleanup
}
You can also create your own error with throw new Error("message").
Example
function readName(user) {
try {
const name = user.profile.name.toUpperCase();
return name;
} catch (error) {
if (error instanceof TypeError) {
return "Unknown user";
}
throw error;
}
}
console.log(readName({ profile: { name: "ada" } }));
console.log(readName(null));
Part by part: user.profile.name works when user is an object. When user is null, JavaScript throws a TypeError. The catch block checks the error type. If it is the expected failure, the function returns a safe fallback. If it is another error, throw error sends it upward so it is not hidden.
Common mistakes
- Catching everything silently. An empty
catchblock hides bugs. Fix it by logging the error or rethrowing unexpected errors. - Using
try/catchfor normal control flow. If a value is often missing, check it first withifor optional chaining. Fix it by reserving exceptions for exceptional cases. - Assuming
error.messageis stable. Messages can change across environments. Fix it by usingerror instanceof TypeErroror a custom error code. - Forgetting that
finallystill runs. It runs even afterreturnorthrow. Fix it by using it only for cleanup, not for changing the result.
When to use it
Use try/catch when failure is possible but not routine, such as parsing JSON, calling an API, or reading a file. Use ordinary checks when missing values are expected, such as validating form input.
| Approach | Best for | Example |
|---|---|---|
if checks | Expected missing data | if (!user) return; |
try/catch | Unexpected runtime failures | JSON.parse(text) |
throw new Error() | Custom failure conditions | throw new Error("Invalid age") |
Practice
Guided exercise: Write a function called parseConfig(text) that uses try/catch to parse JSON. If parsing fails, return {}.
function parseConfig(text) {
try {
return JSON.parse(text);
} catch (error) {
return {};
}
}
Challenge: Modify readName so it also handles a missing profile property. Expected output for readName({}) is "Unknown user".
Quick check
Question: What kind of error occurs when you access a property on null?
Answer: A TypeError, because JavaScript cannot read a property from a value that has no properties.
Summary
JavaScript errors are runtime signals that something unexpected happened. Handling them with try/catch lets your program recover, report problems, and keep running. The key transferable idea is to catch only the failures you understand and let unexpected bugs surface.