try / catch / finally
A statement that allows you to test a block of code for errors, handle them gracefully, and execute cleanup code regardless of whether an error occurred.
try { // code that might throw an error } catch (error) { // code to handle the error } finally { // code that always runs }This static page keeps the syntax and examples indexed for search, while the coding app handles interactive exploration and saved references.
What it does
Overview
A statement that allows you to test a block of code for errors, handle them gracefully, and execute cleanup code regardless of whether an error occurred.
The `try...catch...finally` statement is JavaScript's primary mechanism for structured error handling, enabling robust and resilient applications. The `try` block contains the code that you suspect might throw an error (an exception). If an error occurs within the `try` block, execution immediately stops at the point of the error and jumps to the `catch` block. The `catch` block receives the error object as an argument, allowing you to gracefully handle the error, log it, display a user-friendly message, or attempt to recover from the failure without crashing the entire application. The `finally` block is optional and contains code that will always execute, regardless of whether an error occurred in the `try` block, was caught by `catch`, or even if a `return` statement was encountered. This makes `finally` ideal for cleanup operations, such as closing files, releasing network connections, or resetting UI states, ensuring that these actions are performed consistently even in the presence of exceptions. Proper use of `try...catch...finally` significantly improves application robustness, maintainability, and user experience by preventing unexpected crashes and providing clear feedback when things go wrong.
Quick reference
Syntax
try { // code that might throw an error } catch (error) { // code to handle the error } finally { // code that always runs }
See it in practice
Examples
Basic error catching
function divide(a, b) {
try {
if (b === 0) {
throw new Error('Division by zero is not allowed.');
}
return a / b;
} catch (error) {
console.error('An error occurred:', error.message);
return NaN; // Return a default/error value
}
}
console.log('Result 1:', divide(10, 2));
console.log('Result 2:', divide(10, 0));Result 1: 5 An error occurred: Division by zero is not allowed. Result 2: NaN
The `divide` function attempts division. If `b` is 0, it throws an error. The `catch` block intercepts this error, logs a message, and returns `NaN`, preventing the program from crashing.
Using `finally` for cleanup
function processFile(filename) {
let fileHandle = null;
try {
console.log(`Opening file: ${filename}`);
// Simulate file opening
fileHandle = { id: Math.random(), name: filename };
if (filename === 'error.txt') {
throw new Error('Failed to read file content.');
}
console.log('Processing file content...');
return `Content of ${filename}`;
} catch (error) {
console.error('Error during file processing:', error.message);
return null;
} finally {
if (fileHandle) {
console.log(`Closing file handle for ${fileHandle.name}.`);
// Simulate file closing
fileHandle = null;
}
}
}
console.log(processFile('data.txt'));
console.log(processFile('error.txt'));Opening file: data.txt Processing file content... Closing file handle for data.txt. Content of data.txt Opening file: error.txt Error during file processing: Failed to read file content. Closing file handle for error.txt. null
The `finally` block ensures that the `fileHandle` is always closed, regardless of whether the file processing succeeded or failed with an error. This is crucial for resource management.
Handling asynchronous errors with `async/await`
async function fetchData(url) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error('Failed to fetch data:', error.message);
return null;
}
}
async function runFetches() {
console.log('Fetching valid data...');
const validData = await fetchData('https://jsonplaceholder.typicode.com/todos/1');
console.log('Valid data:', validData ? validData.title : 'N/A');
console.log('\nFetching invalid data...');
const invalidData = await fetchData('https://jsonplaceholder.typicode.com/nonexistent');
console.log('Invalid data:', invalidData);
}
runFetches();Fetching valid data... Valid data: delectus aut autem Fetching invalid data... Failed to fetch data: HTTP error! Status: 404 Invalid data: null
When using `async/await`, `try...catch` blocks can directly wrap `await` expressions to handle errors that occur during asynchronous operations, such as network requests.
Debug faster
Common Errors
Not catching asynchronous errors (outside of `async` functions)
Cause: A `try...catch` block will only catch synchronous errors. Errors thrown inside a `setTimeout` callback, a Promise's executor, or an event handler (unless the handler itself is `async`) will not be caught by an outer `try...catch`.
Fix: For Promises, use `.catch()` or `async/await` with `try...catch`. For `setTimeout` or event handlers, place `try...catch` *inside* the callback function.
try {
setTimeout(() => {
throw new Error('Async error!'); // This error will not be caught here
}, 100);
} catch (e) {
console.error('Caught:', e.message); // This will not run
}Runtime support
Compatibility
Source: MDN Web Docs
Common questions
Frequently Asked Questions
A statement that allows you to test a block of code for errors, handle them gracefully, and execute cleanup code regardless of whether an error occurred.
Not catching asynchronous errors (outside of `async` functions): For Promises, use `.catch()` or `async/await` with `try...catch`. For `setTimeout` or event handlers, place `try...catch` *inside* the callback function.