try...catch

由於本文件沒有此語言的翻譯版本,您閱讀的是英文版的內容。 幫助我們翻譯這篇文章!

The try...catch statement marks a block of statements to try, and specifies a response, should an exception be thrown.

Syntax

try {
  try_statements
}
[catch (exception_var_1 if condition_1) { // non-standard
  catch_statements_1
}]
...
[catch (exception_var_2) {
  catch_statements_2
}]
[finally {
  finally_statements
}]
try_statements
The statements to be executed.
catch_statements_1, catch_statements_2
Statements that are executed if an exception is thrown in the try-block.
exception_var_1, exception_var_2
An identifier to hold an exception object for the associated catch-block.
condition_1
A conditional expression.
finally_statements
Statements that are executed after the try statement completes. These statements execute regardless of whether an exception was thrown or caught.

Description

The try statement consists of a try-block, which contains one or more statements. {} must always be used, even for single statements. At least one catch-block, or a finally-block, must be present. This gives us three forms for the try statement:

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

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 after the try-block and catch-block(s) have finished executing. 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 for more information on JavaScript exceptions.

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.

try {
  throw 'myException'; // 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 scope of the catch-block.

Conditional catch-blocks

Non-standard
This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.

You can also use one or more conditional catch-blocks to handle specific exceptions. In this case, the appropriate catch-block is entered when the specified exception is thrown. In the following example, code in the try-block can potentially throw three exceptions: TypeError, RangeError, and EvalError. When an exception occurs, control transfers to the appropriate catch-block. If the exception is not one of the specified exceptions and an unconditional catch-block is found, control transfers to that catch-block.

If you use an unconditional catch-block with one or more conditional catch-blocks, the unconditional catch-block must be specified last. Otherwise, the unconditional catch-block will intercept all types of exception before they can reach the conditional ones.

Reminder: this functionality is not part of the ECMAScript specification and has been removed in Firefox 59. It's not supported in any current browser anymore.

try {
  myroutine(); // may throw three types of exceptions
} catch (e if e instanceof TypeError) {
  // statements to handle TypeError exceptions
} catch (e if e instanceof RangeError) {
  // statements to handle RangeError exceptions
} catch (e if e instanceof EvalError) {
  // statements to handle EvalError exceptions
} catch (e) {
  // statements to handle any unspecified exceptions
  logMyErrors(e); // pass exception object to error handler
}

Here is the same "Conditional catch-blocks" using code that conforms to ECMAScript specification (obviously it's verbose, but works everywhere):

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
  }
}

The exception identifier

When an exception is thrown in the try-block, exception_var (i.e., the e in catch (e)) holds the exception value. You can use this identifier to get information about the exception that was thrown. This identifier is only available in the catch-block's scope.

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. Note that the finally-block executes regardless of whether an exception is thrown. Also, if an exception is thrown, the statements in the finally-block execute even if no catch-block handles the exception.

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.

openMyFile();
try {
  // tie up a resource
  writeMyFile(theData);
}
finally {
  closeMyFile(); // always close the resource
}

Examples

Nested try-blocks

First, let's see what happens with this:

try {
  try {
    throw new Error('oops');
  }
  finally {
    console.log('finally');
  }
}
catch (ex) {
  console.error('outer', ex.message);
}

// Output:
// "finally"
// "outer" "oops"

Now, if we already caught the exception in the inner try-block by adding a catch-block

try {
  try {
    throw new Error('oops');
  }
  catch (ex) {
    console.error('inner', ex.message);
  }
  finally {
    console.log('finally');
  }
}
catch (ex) {
  console.error('outer', ex.message);
}

// Output:
// "inner" "oops"
// "finally"

And now, let's rethrow the error.

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);
}

// Output:
// "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:

(function() {
  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);
  }
})();

// Output:
// "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

Specification Status Comment
ECMAScript 3rd Edition (ECMA-262) Standard Initial definition. Implemented in JavaScript 1.4
ECMAScript 5.1 (ECMA-262)
The definition of 'try statement' in that specification.
Standard
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'try statement' in that specification.
Standard
ECMAScript Latest Draft (ECMA-262)
The definition of 'try statement' in that specification.
Draft Not part of the current ECMA-262 standard: Multiple catch-blocks and conditional-blocks (SpiderMonkey extension, JavaScript 1.5).

Browser compatibility

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
try...catchChrome Full support 1Edge Full support 12Firefox Full support 1IE Full support 5Opera Full support YesSafari Full support YesWebView Android Full support 1Chrome Android Full support 18Firefox Android Full support 4Opera Android Full support YesSafari iOS Full support YesSamsung Internet Android Full support 1.0nodejs Full support Yes
Conditional clauses
DeprecatedNon-standard
Chrome No support NoEdge No support NoFirefox No support 1 — 59IE No support NoOpera No support NoSafari No support NoWebView Android No support NoChrome Android No support NoFirefox Android No support 4 — 59Opera Android No support NoSafari iOS No support NoSamsung Internet Android No support Nonodejs No support No
Optional catch bindingChrome Full support 66Edge No support NoFirefox Full support 58IE No support NoOpera Full support 53Safari Full support 11.1WebView Android Full support 66Chrome Android Full support 66Firefox Android Full support 58Opera Android Full support 47Safari iOS Full support 11.3Samsung Internet Android Full support 9.0nodejs Full support 10.0.0

Legend

Full support  
Full support
No support  
No support
Non-standard. Expect poor cross-browser support.
Non-standard. Expect poor cross-browser support.
Deprecated. Not for use in new websites.
Deprecated. Not for use in new websites.

See also