JavaScript Try/Catch Synchronous Error Handling
In programming, errors (also called Exceptions) are inevitable. A user might enter the wrong data type, or a variable you expect to exist might be missing. Without error handling, these issues cause your program to “crash” or stop executing entirely.
The try...catch statement allows you to “trap” these errors, handle them gracefully, and keep your application running.
The Try/Catch Syntax
The structure consists of a try block where you place the code you want to run, and a catch block that executes only if an error occurs in the try block.
console.log("Program Started...");
// const someUndefinedVariable = 2; (enable for try block w/out error)
try {
// Code that might throw an error
// 'someUndefinedVariable' does not exist, so JS creates an Error Object here
const result = 10 / someUndefinedVariable;
// 🛑 GUARD: This line will NEVER run if the error occurs above.
console.log("This success message will be skipped.");
} catch (error) {
// 🛡️ SAFETY NET: Code to handle the error
console.log("An error occurred!");
console.log("Error Message: " + error.message);
}
console.log("Program continues to run...");
/* Output:
Program Started...
An error occurred!
Error Message: someUndefinedVariable is not defined
Program continues to run...
*/JavaScriptThe Error Object
When an error occurs, JavaScript generates an Error Object and passes it into the catch block (usually named error or e). You might wonder: Where does that error variable come from?
When JavaScript encounters a crash, it automatically performs three steps in milliseconds:
- Pauses execution.
- Constructs a new object using the
Errorclass (populating it with details likename,message, andstack). - Throws this object into your
catchblock.
This object usually contains:
error.name: The type of error (e.g.,ReferenceError,SyntaxError).error.message: A human-readable string describing the problem.error.stack: A technical trace of where the error happened in the file.
Examples of different Error types that can be caught or generated via Try/Catch:
const num = 1.23;
try {
// Note: the code stops executing in the try block at the first error.
// Change commenting // to see individual error types in console.
console.log(noVariableSet); // ReferenceError
//console.log(num.toUpperCase()); // TypeError
//console.log(num.toFixed(101)); // RangeError (you can only have 100 decimal places)
//console.log(JSON.parse('{"name":"Bob}')); // SyntaxError (missing " after Bob")
//decodeURI("%") // URIError (Uniform Resource Identifier)
//throw new Error("My custom error message."); // Custom Error object message
} catch (myError) {
console.log("Error Name: " + myError.name)
console.log("Error Message: " + myError.message);
console.log("Error Stack: " + myError.stack);
}
/* Output:
Error Name: ReferenceError
Error Message: noVariableSet is not defined
Error Stack: ReferenceError: noVariableSet is not defined
at index.html:14:14
*/JavaScriptReal World Use Case: JSON Parsing
One of the most common uses for synchronous try/catch is handling data from external sources, specifically JSON.parse(). If the data is malformed, JSON.parse() will crash your app immediately. You cannot prevent this with an if statement; you must use try/catch.
const badData = '{"name": "John", "age": 30, }'; // ❌ Syntax Error (trailing comma)
try {
const user = JSON.parse(badData);
console.log("User parsed successfully:", user.name);
} catch (e) {
console.log("⚠️ Data corrupted. Using default guest user.");
console.log("Error:", e.name);
console.log("Technical reason:", e.message);
}
/* Output:
⚠️ Data corrupted. Using default guest user.
Error: SyntaxError
Technical reason: Expected double-quoted property name in JSON at position 28 (line 1 column 29)
(The technical reason above may vary by browser)
*/JavaScriptThe finally Block (Optional)
The finally block is a special section that runs no matter what, regardless of whether an error was caught or not. It is often used for “cleanup” tasks, such as hiding a loading spinner or closing a database connection. The finally block can ensure that code critical for the program’s state runs, even if an exception occurs.
try {
console.log(undefinedVar);
//console.log("Try Block");
} catch (error) {
console.log("Catch Error: " + error.message + " " + error.name);
} finally {
console.log("This is the finally block (always runs).");
}
/* Output:
Catch Error: undefinedVar is not defined ReferenceError
This is the finally block (always runs).
*/JavaScriptThrowing Custom Errors
Sometimes, code is technically valid JavaScript but “wrong” for your specific application logic (e.g., a user enters a negative age). You can manually trigger the catch block using the throw keyword.
When you throw, you are the one creating the Error object and defining the .message property.
function checkAge(age) {
if (age < 0) {
// Manually trigger an error with a custom message
throw new Error("Age cannot be negative!");
}
return "Age is valid.";
}
try {
console.log(checkAge(-5)); // Passing negative value to the CheckAge function.
} catch (e) {
console.log("Validation Failed: " + e.message); // Custom Error message.
}
// Output: Validation Failed: Age cannot be negative!JavaScriptImportant Considerations
- Synchronous Only: The standard
try...catchblock does not catch errors in asynchronous code (likesetTimeoutor network requests). Those require different techniques (Promises/Async-Await) which are covered in a later module. - Control Flow vs. Error Handling: Do not use
try/catchfor simple logic.- Bad:
try { return arr[0] } catch { return null }(Use anifstatement). - Good:
try { JSON.parse(data) } catch { return null }(Because parsing cannot be checked withif).
- Bad:
- Silent Failures: Avoid empty catch blocks (
catch (e) {}). If you “swallow” the error without logging it, you will have a very hard time debugging your code later.
In conclusion: the try…catch statement synchronously executes a block of code and provides a mechanism to elegantly handle and recover from any exceptions (errors) that occur within that block.




