JavaScript try/catch/finally keywords
last modified April 16, 2025
In this article we show how to handle errors using the try/catch/finally
keywords in JavaScript.
The try/catch/finally keywords
The try/catch/finally
statement marks a block of code to try and
specifies a response should an exception be thrown. It allows graceful error
handling rather than abrupt program termination.
The try
block contains code that might throw an exception. The
catch
block contains code to handle the exception. The
finally
block executes after try/catch regardless of outcome.
JavaScript errors can be thrown by the runtime or explicitly using the
throw
statement. The try/catch/finally construct provides
structured exception handling similar to other programming languages.
Basic try/catch example
The following example demonstrates the basic usage of try/catch.
try { let result = riskyOperation(); console.log(result); } catch (error) { console.log('An error occurred:', error.message); }
This code attempts to execute riskyOperation()
which might throw
an error. If an error occurs, execution jumps to the catch block. The error
object contains details about what went wrong.
$ node main.js An error occurred: riskyOperation is not defined
Catching specific error types
JavaScript allows catching specific error types for more precise handling.
try { JSON.parse('invalid json'); } catch (error) { if (error instanceof SyntaxError) { console.log('Syntax error:', error.message); } else { console.log('Unexpected error:', error); } }
This example specifically checks for SyntaxError
when parsing JSON.
Different error types can be handled differently. The instanceof
operator checks the error type.
$ node main.js Syntax error: Unexpected token i in JSON at position 0
The finally block
The finally
block executes regardless of whether an error occurred.
let connection = { open: true }; try { console.log('Using connection'); throw new Error('Network failure'); } catch (error) { console.log('Error:', error.message); } finally { connection.open = false; console.log('Connection closed'); }
Here, finally
ensures the connection is properly closed even if
an error occurs. This is useful for cleanup operations like closing files or
database connections.
$ node main.js Using connection Error: Network failure Connection closed
Nested try/catch blocks
Try/catch blocks can be nested to handle errors at different levels.
try { try { nonExistentFunction(); } catch (innerError) { console.log('Inner catch:', innerError.message); throw new Error('Wrapped error'); } } catch (outerError) { console.log('Outer catch:', outerError.message); }
This example shows nested error handling. The inner catch handles the initial error, then throws a new error caught by the outer catch. This allows error wrapping and rethrowing.
$ node main.js Inner catch: nonExistentFunction is not defined Outer catch: Wrapped error
Custom error throwing
You can throw custom errors using the throw
statement.
function validateAge(age) { if (age < 0) { throw new Error('Age cannot be negative'); } if (age > 120) { throw new RangeError('Age seems invalid'); } return age; } try { validateAge(150); } catch (error) { console.log(error.name + ':', error.message); }
This function throws different error types based on validation failures. Custom errors provide meaningful feedback about what went wrong. Error types help categorize different failure scenarios.
$ node main.js RangeError: Age seems invalid
Async/await with try/catch
Try/catch works with async functions to handle promise rejections.
async function fetchData() { try { let response = await fetch('https://invalid.url'); let data = await response.json(); console.log(data); } catch (error) { console.log('Fetch failed:', error.message); } } fetchData();
This example shows error handling in async code. The try/catch block catches both network errors and JSON parsing errors. Async/await makes promise-based error handling more intuitive.
$ node main.js Fetch failed: fetch failed
Error object properties
Error objects contain useful properties for debugging.
try { null.someProperty; } catch (error) { console.log('Name:', error.name); console.log('Message:', error.message); console.log('Stack:', error.stack.split('\n')[0]); }
This code demonstrates common error properties. The name
identifies
the error type. message
provides a human-readable description.
stack
contains the call stack trace for debugging.
$ node main.js Name: TypeError Message: Cannot read properties of null (reading 'someProperty') Stack: TypeError: Cannot read properties of null (reading 'someProperty')
Source
try/catch - language reference
In this article we have demonstrated how to use try/catch/finally for error handling in JavaScript.