AbdulElahGwaith's picture
Upload folder using huggingface_hub
780c9fe verified
---
title: try...catch
slug: Web/JavaScript/Reference/Statements/try...catch
page-type: javascript-statement
browser-compat: javascript.statements.try_catch
sidebar: jssidebar
---
The **`try...catch`** statement is comprised of a `try` block and either a `catch` block, a `finally` block, or both. The code in the `try` block is executed first, and if it throws an exception, the code in the `catch` block will be executed. The code in the `finally` block will always be executed before control flow exits the entire construct.
{{InteractiveExample("JavaScript Demo: try...catch statement")}}
```js interactive-example
try {
nonExistentFunction();
} catch (error) {
console.error(error);
// Expected output: ReferenceError: nonExistentFunction is not defined
// (Note: the exact output may be browser-dependent)
}
```
## Syntax
```js-nolint
try {
tryStatements
} catch (exceptionVar) {
catchStatements
} finally {
finallyStatements
}
```
- `tryStatements`
- : The statements to be executed.
- `catchStatements`
- : Statement that is executed if an exception is thrown in the `try` block.
- `exceptionVar` {{optional_inline}}
- : An optional [identifier or pattern](#catch_binding) to hold the caught exception for the associated `catch` block. If the `catch` block does not use the exception's value, you can omit the `exceptionVar` and its surrounding parentheses.
- `finallyStatements`
- : Statements that are executed before control flow exits the `try...catch...finally` construct. These statements execute regardless of whether an exception was thrown or caught.
## Description
The `try` statement always starts with a `try` block. Then, a `catch` block or a `finally` block must be present. It's also possible to have both `catch` and `finally` blocks. This gives us three forms for the `try` statement:
- `try...catch`
- `try...finally`
- `try...catch...finally`
Unlike other constructs such as [`if`](/en-US/docs/Web/JavaScript/Reference/Statements/if...else) or [`for`](/en-US/docs/Web/JavaScript/Reference/Statements/for), the `try`, `catch`, and `finally` blocks must be _blocks_, instead of single statements.
```js-nolint example-bad
try doSomething(); // SyntaxError
catch (e) console.log(e);
```
A `catch` block contains statements that specify what to do if an exception is thrown in the `try` block. If any statement within the `try` block (or in a function called from within the `try` block) throws an exception, control is immediately shifted to the `catch` block. If no exception is thrown in the `try` block, the `catch` block is skipped.
The `finally` block will always execute before control flow exits the `try...catch...finally` construct. It always executes, regardless of whether an exception was thrown or caught.
You can nest one or more `try` statements. If an inner `try` statement does not have a `catch` block, the enclosing `try` statement's `catch` block is used instead.
You can also use the `try` statement to handle JavaScript exceptions. See the [JavaScript Guide](/en-US/docs/Web/JavaScript/Guide/Control_flow_and_error_handling#exception_handling_statements) for more information on JavaScript exceptions.
### Catch binding
When an exception is thrown in the `try` block, `exceptionVar` (i.e., the `e` in `catch (e)`) holds the exception value. You can use this {{Glossary("binding")}} to get information about the exception that was thrown. This {{Glossary("binding")}} is only available in the `catch` block's {{Glossary("Scope", "scope")}}.
It doesn't need to be a single identifier. You can use a [destructuring pattern](/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring) to assign multiple identifiers at once.
```js
try {
throw new TypeError("oops");
} catch ({ name, message }) {
console.log(name); // "TypeError"
console.log(message); // "oops"
}
```
The bindings created by the `catch` clause live in the same scope as the `catch` block, so any variables declared in the `catch` block cannot have the same name as the bindings created by the `catch` clause. (There's [one exception to this rule](/en-US/docs/Web/JavaScript/Reference/Deprecated_and_obsolete_features#statements), but it's a deprecated syntax.)
```js-nolint example-bad
try {
throw new TypeError("oops");
} catch ({ name, message }) {
var name; // SyntaxError: Identifier 'name' has already been declared
let message; // SyntaxError: Identifier 'message' has already been declared
}
```
The exception binding is writable. For example, you may want to normalize the exception value to make sure it's an {{jsxref("Error")}} object.
```js
try {
throw "Oops; this is not an Error object";
} catch (e) {
if (!(e instanceof Error)) {
e = new Error(e);
}
console.error(e.message);
}
```
If you don't need the exception value, you can omit it along with the enclosing parentheses.
```js
function isValidJSON(text) {
try {
JSON.parse(text);
return true;
} catch {
return false;
}
}
```
### The finally block
The `finally` block contains statements to execute after the `try` block and `catch` block(s) execute, but before the statements following the `try...catch...finally` block. Control flow will always enter the `finally` block, which can proceed in one of the following ways:
- Immediately after the `try` block finishes execution normally (and no exceptions were thrown);
- Immediately after the `catch` block finishes execution normally;
- Immediately before the execution of a control-flow statement (`return`, `throw`, `break`, `continue`) in the `try` block or `catch` block that would exit the block.
If an exception is thrown from the `try` block, even when there's no `catch` block to handle the exception, the `finally` block still executes, in which case the exception is still thrown immediately after the `finally` block finishes executing.
The following example shows one use case for the `finally` block. The code opens a file and then executes statements that use the file; the `finally` block makes sure the file always closes after it is used even if an exception was thrown.
```js
openMyFile();
try {
// tie up a resource
writeMyFile(theData);
} finally {
closeMyFile(); // always close the resource
}
```
Control flow statements (`return`, `throw`, `break`, `continue`) in the `finally` block will "mask" any completion value of the `try` block or `catch` block. In this example, the `try` block tries to return 1, but before returning, the control flow is yielded to the `finally` block first, so the `finally` block's return value is returned instead.
```js
function doIt() {
try {
return 1;
} finally {
return 2;
}
}
doIt(); // returns 2
```
It is generally a bad idea to have control flow statements in the `finally` block. Only use it for cleanup code.
## Examples
### Unconditional catch block
When a `catch` block is used, the `catch` block is executed when any exception is thrown from within the `try` block. For example, when the exception occurs in the following code, control transfers to the `catch` block.
```js
try {
throw new Error("My exception"); // generates an exception
} catch (e) {
// statements to handle any exceptions
logMyErrors(e); // pass exception object to error handler
}
```
The `catch` block specifies an identifier (`e` in the example above) that holds the value of the exception; this value is only available in the {{Glossary("Scope", "scope")}} of the `catch` block.
### Conditional catch blocks
You can create "Conditional `catch` blocks" by combining `try...catch` blocks with `if...else if...else` structures, like this:
```js
try {
myRoutine(); // may throw three types of exceptions
} catch (e) {
if (e instanceof TypeError) {
// statements to handle TypeError exceptions
} else if (e instanceof RangeError) {
// statements to handle RangeError exceptions
} else if (e instanceof EvalError) {
// statements to handle EvalError exceptions
} else {
// statements to handle any unspecified exceptions
logMyErrors(e); // pass exception object to error handler
}
}
```
A common use case for this is to only catch (and silence) a small subset of expected errors, and then re-throw the error in other cases:
```js
try {
myRoutine();
} catch (e) {
if (e instanceof RangeError) {
// statements to handle this very common expected error
} else {
throw e; // re-throw the error unchanged
}
}
```
This may mimic the syntax from other languages, like Java:
```java
try {
myRoutine();
} catch (RangeError e) {
// statements to handle this very common expected error
}
// Other errors are implicitly re-thrown
```
### Nested try blocks
First, let's see what happens with this:
```js
try {
try {
throw new Error("oops");
} finally {
console.log("finally");
}
} catch (ex) {
console.error("outer", ex.message);
}
// Logs:
// "finally"
// "outer" "oops"
```
Now, if we already caught the exception in the inner `try` block by adding a `catch` block:
```js
try {
try {
throw new Error("oops");
} catch (ex) {
console.error("inner", ex.message);
} finally {
console.log("finally");
}
} catch (ex) {
console.error("outer", ex.message);
}
// Logs:
// "inner" "oops"
// "finally"
```
And now, let's rethrow the error.
```js
try {
try {
throw new Error("oops");
} catch (ex) {
console.error("inner", ex.message);
throw ex;
} finally {
console.log("finally");
}
} catch (ex) {
console.error("outer", ex.message);
}
// Logs:
// "inner" "oops"
// "finally"
// "outer" "oops"
```
Any given exception will be caught only once by the nearest enclosing `catch` block unless it is rethrown. Of course, any new exceptions raised in the "inner" block (because the code in `catch` block may do something that throws), will be caught by the "outer" block.
### Returning from a finally block
If the `finally` block returns a value, this value becomes the return value of the entire `try-catch-finally` statement, regardless of any `return` statements in the `try` and `catch` blocks. This includes exceptions thrown inside of the `catch` block:
```js
(() => {
try {
try {
throw new Error("oops");
} catch (ex) {
console.error("inner", ex.message);
throw ex;
} finally {
console.log("finally");
return;
}
} catch (ex) {
console.error("outer", ex.message);
}
})();
// Logs:
// "inner" "oops"
// "finally"
```
The outer "oops" is not thrown because of the return in the `finally` block. The same would apply to any value returned from the `catch` block.
## Specifications
{{Specifications}}
## Browser compatibility
{{Compat}}
## See also
- {{jsxref("Error")}}
- {{jsxref("Statements/throw", "throw")}}