Synchronous Error Handling in JavaScript
Master try/catch/finally for robust error handling in synchronous JavaScript code
Introduction
Error handling is crucial for building robust applications. Synchronous error handling in JavaScript uses try/catch/finally blocks to gracefully handle exceptions.
Try/Catch/Finally Basics
The Try Block
Contains code that might throw:
function toUppercase(string) {
if (typeof string !== 'string') {
throw TypeError('Wrong type given, expected a string');
}
return string.toUpperCase();
}
try {
toUppercase(4); // Throws error
} catch (error) {
console.error(error.message);
}
The Catch Block
Handles exceptions:
try {
riskyOperation();
} catch (error) {
console.error('Operation failed:', error.message);
logErrorToService(error);
showUserMessage('Something went wrong');
}
The Finally Block
Always runs, perfect for cleanup:
try {
const data = loadData();
processData(data);
} catch (error) {
console.error('Failed:', error.message);
} finally {
hideLoadingSpinner(); // Always runs
}
Error Types
Built-in Errors
// TypeError
try {
null.someMethod();
} catch (error) {
if (error instanceof TypeError) {
// Handle type error
}
}
// SyntaxError
try {
JSON.parse('invalid json');
} catch (error) {
if (error instanceof SyntaxError) {
// Handle syntax error
}
}
Custom Errors
class ValidationError extends Error {
constructor(message, field) {
super(message);
this.name = 'ValidationError';
this.field = field;
}
}
try {
throw new ValidationError('Email required', 'email');
} catch (error) {
if (error instanceof ValidationError) {
console.error(`Field ${error.field}: ${error.message}`);
}
}
Best Practices
Be Specific
try {
doSomething();
} catch (error) {
if (error instanceof NetworkError) {
retry();
} else {
throw error;
}
}
Always Log Errors
try {
riskyOperation();
} catch (error) {
console.error('Operation failed:', {
message: error.message,
stack: error.stack
});
}
Clean Up in Finally
let connection;
try {
connection = connect();
doWork(connection);
} finally {
if (connection) {
connection.close(); // Always close
}
}
Important: Try/Catch is Synchronous Only
// ❌ Won't catch async errors
try {
setTimeout(() => {
throw new Error('Won\'t be caught!');
}, 1000);
} catch (error) {
// Never reaches here
}
Conclusion
Use try/catch/finally for synchronous error handling. Always log errors, clean up resources, and remember it only works for sync code.
#javascript #error-handling #best-practices