try...catch

この記事は翻訳が完了していません。 この記事の翻訳にご協力ください

try...catch 文は、試す文のブロックをマークし、例外が発生したときの応答を指定します。

構文

try {
  try_statements
}
[catch (exception_var_1 if condition_1) { // 標準外
  catch_statements_1
}]
...
[catch (exception_var_2) {
  catch_statements_2
}]
[finally {
  finally_statements
}]
try_statements
実行される文です。
catch_statements_1, catch_statements_2
try ブロックの中で例外が発生した場合に実行される文です。
exception_var_1, exception_var_2
関連する catch 節に対して例外オブジェクトを保持する識別子です。
condition_1
条件式です。
finally_statements
try 文が完了した後に実行される文です。これらの文は、例外が発生されたり捕捉されたりしたかどうかに関係なく実行されます。

解説

try 文は、1つ以上の文を含む try ブロックにより構成されます。文が1つであっても、常に {} を使用する必要があります。1つ以上の catch ブロック、または finally ブロックが存在する必要があります。すなわち、 try 文には 3 つの形態があります。

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

catch ブロックは、例外が try ブロックの中で発生した場合に何をするかを指定する文を含みます。 try ブロック内 (または try ブロック内から呼び出された関数の中) のいずれかの文で例外が発生した場合は、制御は即座に catch ブロックへ移ります。 try ブロックの中で例外が発生しなかった場合は、 catch ブロックは飛ばされます。

finally ブロックは、 try ブロックおよび catch ブロックの実行が完了した後で実行されます。これは常に実行され、例外が発生したかどうか、捕捉されたかどうかには関係ありません。

1 つ以上の try 文を入れ子にする事ができます。内側の try 文が catch ブロックを持っていない場合、それを囲んでいる try 文の catch ブロックに入ります。

try を使用して JavaScript の例外を処理することもできます。 JavaScript の例外に関する情報は JavaScript ガイドを参照してください。

無条件の catch ブロック

catch ブロックが使われている場合、 try ブロックの中から任意の例外が発生すると、 catch ブロックが実行されます。例えば、以下のコードで例外が発生すると、制御は catch ブロックへ移動します。

try {
  throw 'myException'; // 例外を生成
}
catch (e) {
  // 任意の例外を操作するための文
  logMyErrors(e); // エラーハンドラーに例外オブジェクトを渡します
}

catch ブロックは例外の値を保持する識別子 (上記の例では e) を指定します。この値は catch ブロックのスコープ内でのみ利用できます。

条件付き catch ブロック

「条件付き catch ブロック」は、下記のように try...catch ブロックを if...else if...else 構造と組み合わせることで作成することができます。

try {
  myroutine(); // 3 つの例外を投げる可能性があります
} catch (e) {
  if (e instanceof TypeError) {
    // TypeError 例外を処理するための文
  } else if (e instanceof RangeError) {
    // RangeError 例外を処理するための文
  } else if (e instanceof EvalError) {
    // EvalError 例外を処理するための文
  } else {
    // 任意の指定されていない例外を操作するための文
    logMyErrors(e); // エラーハンドラーに例外オブジェクトを渡す
  }
}

よくある使用例としては、次のように想定済みの一部のエラーのみを捕捉 (および無視) し、それ以外の場合はエラーを送出し直す場合です。

try {
  myRoutine();
} catch (e) {
  if (e instanceof RangeError) {
    // 頻発する想定済みのエラーを処理する文
  } else {
    throw e;  // エラーを変更しないまま送出し直す
  }
}

例外識別子

例外が try ブロックの中で投げられたときは、exception_var (たとえば、 catch (e) における e) が例外の値を保持します。この識別子を使用して、発生した例外についての情報を取得することができます。この識別子は catch ブロックのスコープでのみ利用できます。

function isValidJSON(text) {
  try {
    JSON.parse(text);
    return true;
  } catch {
    return false;
  }
}

finally ブロック

finally ブロックには、 try ブロックおよび catch ブロックを実行した後で、 try...catch...finally の次の文が実行される前に実行される文が入ります。なお、 finally ブロックは例外が発生するかどうかにかかわらず実行されます。また、例外が発生した場合、 finally ブロックは例外を処理する catch ブロックがなくても実行されます。

次の例では finally ブロックの一つの使用例を示します。このコードはファイルを開き、それからファイルを使用する分を実行します。 finally ブロックは、例外が発生したとしてもその後で確実にファイルを閉じるよう保証します。

openMyFile();
try {
  // リソースを結び付けます
  writeMyFile(theData);
}
finally {
  closeMyFile(); // リソースを常に閉じます
}

入れ子になった try ブロック

最初に、次のもので何が起きるか見てみましょう。

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

// 出力:
// "finally"
// "outer" "oops"

ここで、既に内部の try ブロックに catch ブロックを追加しているので、既に例外を捕捉しています。

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

// 出力:
// "inner" "oops"
// "finally"

そして、エラーを送りなおします。

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

// 出力:
// "inner" "oops"
// "finally"
// "outer" "oops"

送り直されない限り、例外はどれでも最も内側の catch ブロックで一度だけ捕捉されます。もちろん、何らかの例外が「内側の」のブロックで発生した場合 (catch ブロックのコードで例外が発生することを行った場合)、「外側の」ブロックで捕捉されます。

finally ブロックからの return

finally ブロックが値を返した場合、 try ブロックや catch ブロックの return 文に関係なく、その値が try-catch-finally 全体の返値になります。これは catch ブロック内で送出された例外も含みます。

(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"

外側の "oops" は finally ブロックに return があるため送出されません。同じことが、 catch ブロックから返されているそのほかの値にも適用されます。

仕様書

仕様書
ECMAScript (ECMA-262)
try statement の定義

ブラウザーの互換性

Update compatibility data on GitHub
デスクトップモバイルサーバー
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung InternetNode.js
try...catchChrome 完全対応 1Edge 完全対応 12Firefox 完全対応 1IE 完全対応 5Opera 完全対応 4Safari 完全対応 1WebView Android 完全対応 1Chrome Android 完全対応 18Firefox Android 完全対応 4Opera Android 完全対応 10.1Safari iOS 完全対応 1Samsung Internet Android 完全対応 1.0nodejs 完全対応 0.1.100
Optional catch bindingChrome 完全対応 66Edge 完全対応 79Firefox 完全対応 58IE 未対応 なしOpera 完全対応 53Safari 完全対応 11.1WebView Android 完全対応 66Chrome Android 完全対応 66Firefox Android 完全対応 58Opera Android 完全対応 47Safari iOS 完全対応 11.3Samsung Internet Android 完全対応 9.0nodejs 完全対応 10.0.0

凡例

完全対応  
完全対応
未対応  
未対応

関連情報