Safe Code

Even the best code can fail. The try..catch block lets you catch errors gracefully and prevent the entire script from crashing.

try {
  console.log('Start of try block');
  lalala; // Error: variable is not defined!
  console.log('End of try block (never reached)');
} catch (err) {
  console.log('Error caught: ' + err.message);
} finally {
  // Runs ALWAYS — success or failure
  console.log('I always run — great for cleanup!');
}

The finally Block

Use finally for cleanup that must happen regardless of the outcome:

async function loadData() {
  showLoadingSpinner();
  try {
    const data = await fetch('/api/data').then(r => r.json());
    return data;
  } catch (err) {
    showError(err.message);
  } finally {
    hideLoadingSpinner(); // ALWAYS hides — even if an error occurred
  }
}
Caution

try..catch only works for synchronous code. Errors inside setTimeout callbacks will NOT be caught. For async code, use try..catch with async/await or .catch() on promises.

Tip

Use finally when you need to guarantee something runs (e.g., hiding a loading spinner, closing a database connection) regardless of whether the operation succeeded or failed.