Error handling is a crucial part of writing robust and user-friendly applications. In JavaScript, errors can occur due to invalid input, network issues, syntax problems, or unexpected conditions. Instead of letting the program crash, proper error handling allows developers to gracefully manage these issues.
1. What is an Error?
An error in JavaScript is an object that represents a runtime problem. When an error occurs, JavaScript stops executing the remaining code unless the error is handled. JavaScript provides structured ways to detect and deal with these errors using constructs like try...catch
, throw
, and finally
.
2. The try...catch Statement
The try...catch
statement is used to handle exceptions (errors) that occur during the execution of code inside the try
block.
try {
// Code that may throw an error
let result = x + 10; // if x is not defined, error occurs
} catch (error) {
// Code to handle the error
console.error("An error occurred:", error.message);
}
Explanation:
- try: The block of code where errors might occur.
- catch: The block that executes if an error is thrown.
- error: An object representing the error, typically with
name
andmessage
properties.
3. The throw Statement
You can use the throw
statement to create your own custom errors.
function divide(a, b) {
if (b === 0) {
throw new Error("Division by zero is not allowed.");
}
return a / b;
}
try {
console.log(divide(10, 0));
} catch (err) {
console.error("Custom Error:", err.message);
}
Here, we manually check for a condition and throw
an error if it’s violated. This is useful for validating input or enforcing logic constraints.
4. finally Block
The finally
block is used to execute code after try
and catch
, regardless of whether an error occurred or not. This is useful for cleanup operations like closing files, ending sessions, or stopping loaders.
try {
let data = JSON.parse("{ invalid JSON }");
} catch (err) {
console.error("Parsing failed:", err.message);
} finally {
console.log("This block always runs");
}
5. Error Object Properties
JavaScript errors have the following standard properties:
name
– The type of error (e.g.,ReferenceError
,TypeError
)message
– A human-readable description of the errorstack
– Stack trace (helpful for debugging)
try {
let num = unknownVariable;
} catch (error) {
console.log("Name:", error.name);
console.log("Message:", error.message);
console.log("Stack:", error.stack);
}
6. Built-in Error Types
JavaScript provides several built-in error types that help developers identify specific problems:
- ReferenceError – Accessing a variable that hasn't been declared.
- TypeError – Performing an operation on a value of the wrong type.
- SyntaxError – Invalid code syntax.
- RangeError – A numeric value that’s out of range.
- URIError – Malformed URI used in
decodeURI()
orencodeURI()
. - EvalError – Issues with the
eval()
function (rarely used now).
// ReferenceError
try {
console.log(x); // x is not defined
} catch (e) {
console.log("Caught:", e.name); // ReferenceError
}
// TypeError
try {
null.f(); // Cannot call function on null
} catch (e) {
console.log("Caught:", e.name); // TypeError
}
7. Custom Error Classes
You can define your own error types by extending the built-in Error
class. This is useful in large applications to classify different types of errors.
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}
function saveUser(user) {
if (!user.name) {
throw new ValidationError("User must have a name.");
}
console.log("User saved!");
}
try {
saveUser({});
} catch (e) {
console.error(e.name + ": " + e.message);
}
8. Handling Errors in Asynchronous Code
8.1 With Callbacks
function fetchData(callback) {
setTimeout(() => {
try {
// Simulate error
throw new Error("Failed to fetch data");
} catch (err) {
callback(err);
}
}, 1000);
}
fetchData((err) => {
if (err) {
console.log("Callback error:", err.message);
}
});
8.2 With Promises
function asyncTask(success) {
return new Promise((resolve, reject) => {
if (success) {
resolve("Task completed");
} else {
reject(new Error("Task failed"));
}
});
}
asyncTask(false)
.then(result => console.log(result))
.catch(err => console.error("Promise error:", err.message));
8.3 With async/await
async function doWork() {
try {
let result = await asyncTask(false);
console.log(result);
} catch (err) {
console.log("Async/Await Error:", err.message);
}
}
doWork();
9. Real-World Example: Fetch API
When working with APIs, errors can come from the network, server, or invalid responses. Always use try...catch
or .catch()
to handle them.
async function getUserData() {
try {
const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
if (!response.ok) {
throw new Error("Failed to fetch data: " + response.status);
}
const data = await response.json();
console.log("User Data:", data);
} catch (err) {
console.error("Fetch Error:", err.message);
}
}
getUserData();
10. Best Practices for Error Handling
- Always validate user input to prevent runtime errors.
- Use specific error types to make debugging easier.
- Don’t suppress errors silently — log them or show user-friendly messages.
- Use custom error classes in larger applications for clarity.
- Catch errors in async code using try...catch or promise
.catch()
. - Don’t overuse try...catch – only use it where there's a genuine risk of failure.
error handling JavaScript Quiz
1. What is the purpose of the 'catch' block in JavaScript?
2. What is the function of the 'finally' block in a try-catch-finally statement?
3. What does the 'throw' statement do in JavaScript?
4. What does the error object contain in a catch block?
5. How can you create a custom error in JavaScript?
6. Can a 'try' block throw multiple types of errors?
7. Why is it important to use 'try-catch' in your code?
8. How can you create a custom error class in JavaScript?
9. What happens to the 'finally' block if no error occurs in the 'try' block?
10. What is the main benefit of using 'try-catch' for error handling?
11. What is a benefit of creating a custom error class in JavaScript?
12. When does the 'finally' block execute in a try-catch-finally statement?
13. What is the purpose of the 'throw' statement in JavaScript?
14. How can custom error handling improve error management in applications?
15. What is the primary purpose of the 'try' block in JavaScript?
16. Why is it important to catch specific error types in JavaScript?
17. What type of code is typically placed inside a 'try' block?
18. How can you check if an error is of a specific type in JavaScript?
19. Why is error handling important in JavaScript applications?
20. What is the primary function of the 'catch' block in JavaScript?