Movatterモバイル変換


[0]ホーム

URL:


MDN Web Docs

try...catch

BaselineWidely available

Thetry...catch statement is comprised of atry block and either acatch block, afinally block, or both. The code in thetry block is executed first, and if it throws an exception, the code in thecatch block will be executed. The code in thefinally block will always be executed before control flow exits the entire construct.

Try it

try {  nonExistentFunction();} catch (error) {  console.error(error);  // Expected output: ReferenceError: nonExistentFunction is not defined  // (Note: the exact output may be browser-dependent)}

Syntax

js
try {  tryStatements} catch (exceptionVar) {  catchStatements} finally {  finallyStatements}
tryStatements

The statements to be executed.

catchStatements

Statement that is executed if an exception is thrown in thetry block.

exceptionVarOptional

An optionalidentifier or pattern to hold the caught exception for the associatedcatch block. If thecatch block does not use the exception's value, you can omit theexceptionVar and its surrounding parentheses.

finallyStatements

Statements that are executed before control flow exits thetry...catch...finally construct. These statements execute regardless of whether an exception was thrown or caught.

Description

Thetry statement always starts with atry block. Then, acatch block or afinally block must be present. It's also possible to have bothcatch andfinally blocks. This gives us three forms for thetry statement:

  • try...catch
  • try...finally
  • try...catch...finally

Unlike other constructs such asif orfor, thetry,catch, andfinally blocks must beblocks, instead of single statements.

js
try doSomething(); // SyntaxErrorcatch (e) console.log(e);

Acatch block contains statements that specify what to do if an exception is thrown in thetry block. If any statement within thetry block (or in a function called from within thetry block) throws an exception, control is immediately shifted to thecatch block. If no exception is thrown in thetry block, thecatch block is skipped.

Thefinally block will always execute before control flow exits thetry...catch...finally construct. It always executes, regardless of whether an exception was thrown or caught.

You can nest one or moretry statements. If an innertry statement does not have acatch block, the enclosingtry statement'scatch block is used instead.

You can also use thetry statement to handle JavaScript exceptions. See theJavaScript Guide for more information on JavaScript exceptions.

Catch binding

When an exception is thrown in thetry block,exceptionVar (i.e., thee incatch (e)) holds the exception value. You can use thisbinding to get information about the exception that was thrown. Thisbinding is only available in thecatch block'sscope.

It doesn't need to be a single identifier. You can use adestructuring pattern 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 thecatch clause live in the same scope as thecatch block, so any variables declared in thecatch block cannot have the same name as the bindings created by thecatch clause. (There'sone exception to this rule, but it's a deprecated syntax.)

js
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 anError 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

Thefinally block contains statements to execute after thetry block andcatch block(s) execute, but before the statements following thetry...catch...finally block. Control flow will always enter thefinally block, which can proceed in one of the following ways:

  • Immediately after thetry block finishes execution normally (and no exceptions were thrown);
  • Immediately after thecatch block finishes execution normally;
  • Immediately before the execution of a control-flow statement (return,throw,break,continue) in thetry block orcatch block that would exit the block.

If an exception is thrown from thetry block, even when there's nocatch block to handle the exception, thefinally block still executes, in which case the exception is still thrown immediately after thefinally block finishes executing.

The following example shows one use case for thefinally block. The code opens a file and then executes statements that use the file; thefinally 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 thefinally block will "mask" any completion value of thetry block orcatch block. In this example, thetry block tries to return 1, but before returning, the control flow is yielded to thefinally block first, so thefinally 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 thefinally block. Only use it for cleanup code.

Examples

Unconditional catch block

When acatch block is used, thecatch block is executed when any exception is thrown from within thetry block. For example, when the exception occurs in the following code, control transfers to thecatch 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}

Thecatch block specifies an identifier (e in the example above) that holds the value of the exception; this value is only available in thescope of thecatch block.

Conditional catch blocks

You can create "Conditionalcatch blocks" by combiningtry...catch blocks withif...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 innertry block by adding acatch 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 enclosingcatch block unless it is rethrown. Of course, any new exceptions raised in the "inner" block (because the code incatch block may do something that throws), will be caught by the "outer" block.

Returning from a finally block

If thefinally block returns a value, this value becomes the return value of the entiretry-catch-finally statement, regardless of anyreturn statements in thetry andcatch blocks. This includes exceptions thrown inside of thecatch 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 thefinally block. The same would apply to any value returned from thecatch block.

Specifications

Specification
ECMAScript® 2026 Language Specification
# sec-try-statement

Browser compatibility

See also

Help improve MDN

Learn how to contribute.

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp