概要
try…catch 構文は試したい文のブロックをマークし、例外を投げる必要がある場合のレスポンスを指定するための構文です。
構文
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
- 実行される文。
catch_statements_1
,catch_statements_2
- try ブロックの中で例外が投げられた場合に実行される文です。
exception_var_1
,exception_var_2
- 関連する
catch
節に対して例外オブジェクトを保持する識別子。
condition_1
- 条件式。
finally_statements
try
文が完了した後に実行される文。これらの文は、例外が投げられたり捕捉されたかどうかに関係なく実行されます。
説明
try
文は、1 つ以上の文を含む try
ブロック、および少なくとも 1 つの catch
節、または finally
節、もしくはその両方から成り立っています。すなわち、try
文には 3 つの形式があります:
try...catch
try...finally
try...catch...finally
catch
節は、例外が try
ブロックの中で投げられたのなら何をすべきか指定する文を含みます。すなわち、try
ブロックは成功すべきで、それが成功しなかったのなら、制御は catch
ブロックに渡るべきです。try
ブロック内 (または try
ブロック内から呼び出された関数の中) の任意の文が例外を投げたのなら、制御は即座に catch
節へ移ります。例外が try
ブロックの中で投げられなかったのなら、catch
節は飛ばされます。
finally
節は、try
ブロックおよび (1 つまたは複数の) catch
節が実行された後、なおかつ try
文の次の文の前に実行されます。これは、例外が投げられた、または捕捉されたかどうかに関係なく、常に実行されます。
1 つ以上の try
文をネストすることもできます。内側の try
文が catch
節を持たないのなら、囲んでいる try
文の catch
節に入ります。
Java の例外を操作するためにも try
文を使います。Java の例外に関する情報は Core JavaScript 1.5 ガイドを参照してください。
無条件 catch
節
単独の無条件 catch
節が使われたときは、任意の例外が投げられると catch
節に入ります。たとえば、次のコードの中で例外が生じたとき、制御は catch
節に移動します。
try { throw "myException"; // 例外を生成します } catch (e) { // 任意の例外を操作するための文 logMyErrors(e); // エラーハンドラに例外オブジェクトを渡します }
条件付き catch
節
非標準
この機能は標準ではなく、標準化の予定もありません。公開されている Web サイトには使用しないでください。ユーザーによっては使用できないことがあります。実装ごとに大きな差があることもあり、将来は振る舞いが変わるかもしれません。
特定の例外を操作するために、1 つ以上の条件付き catch
節を使うこともできます。この場合、特定の例外が投げられると、適切な catch
節に入ります。次の例では、try
ブロックの中のコードは 3 つの例外: TypeError
、RangeError
、および EvalError
、を投げる可能性があります。例外が生じたとき、制御は適切な catch
節に移動します。例外が、指定された例外のどれでもなく、かつ無条件 catch
節が見つかったのなら、制御はその catch
節に移動します。
1 つ以上の条件付き catch
節とともに無条件 catch
節を使うのなら、無条件 catch
節は最後に指定されなくてはいけません。そうでなければ、無条件 catch
節が全種類の例外を、それらが条件付きのものに到達する前に、途中で捕捉します。
注: この機能は ECMAScript 仕様の一部ではありません。
try { myroutine(); // 3 つの例外を投げる可能性があります } catch (e if e instanceof TypeError) { // TypeError 例外を操作するための文 } catch (e if e instanceof RangeError) { // RangeError 例外を操作するための文 } catch (e if e instanceof EvalError) { // EvalError 例外を操作するための文 } catch (e) { // 任意の指定されていない例外を操作するための文 logMyErrors(e); // エラーハンドラに例外オブジェクトを渡します }
続いて、"条件付きcatch
節"と同じことをECMAScript仕様に準拠したJavaScriptを使って実装する方法も示します(これは明らかに冗長ですが、かわりにどの環境でも動作します):
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
}
}
例外識別子
例外が try
ブロックの中で投げられたときは、exception_var
(たとえば、catch (e)
における e
) が throw
文により指定された値を保持します。投げられた例外についての情報を得るために、この識別子を使うことができます。
この識別子は catch
節にローカルです。すなわち、これは catch
節に入ったときに作成され、catch
節が実行を終了した後では、この識別子はもはや利用できません。
finally
節
finally
節は、try
ブロックおよび (1 つまたは複数の) catch
節が実行された後、なおかつ try
文の次の文の前に実行される文を含みます。finally
節は、例外が投げられたかどうかに関係なく実行されます。例外が投げられたのなら、たとえ例外を操作する catch
節がなかったとしても、finally
節の中の文は実行されます。
例外が生じたときに、スクリプトを潔く失敗させるために finally
節を使うことができます。たとえば、スクリプトが結び付けていたリソースを解放する必要があるかもしれません。次の例ではファイルを開き、そのファイルを使う文を実行します (サーバーサイド JavaScript ではファイルにアクセスできます)。ファイルが開かれている間に例外が投げられたのなら、スクリプトが失敗する前に finally
節はファイルを閉じます。
openMyFile() try { // リソースを結び付けます writeMyFile(theData); } finally { closeMyFile(); // リソースを常に閉じます }
Examples
入れ子になったtryブロック
最初に、これで何が起きるか見てみましょう:
try {
try {
throw new Error("oops");
}
finally {
console.log("finally");
}
}
catch (ex) {
console.error("outer", ex.message);
}
// Output:
// "finally"
// "outer" "oops"
続いて、catch ブロックを追加して内部の try ブロックで例外をキャッチしてみます。
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"
そして、エラーを再スローします。
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"
再スローされない限り任意の例外は、最も内側のキャッチブロックで一度だけ捕捉されます。もちろん、何らかの例外が "内部" のブロックで発生した場合(catch ブロックのコードで何らかのスローが発生した場合)、"外部" のブロックでキャッチされます。
finally ブロックからの return
finally
ブロックが値を返した場合、try
ブロックと catch
ブロックの return
ステートメントにかからわず、この値が try-catch-finally
全体の戻り値になります。これは catch ブロック内でスローされた例外も含みます:
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 3rd Edition (ECMA-262) | 標準 | 初期定義。JavaScript 1.4 で実装されました。 |
ECMAScript 5.1 (ECMA-262) try statement の定義 |
標準 | |
ECMAScript 2015 (6th Edition, ECMA-262) try statement の定義 |
標準 | |
ECMAScript 2017 Draft (ECMA-262) try statement の定義 |
ドラフト | 現在の ECMA-262 標準には含まれていません。複数の catch 節と条件付き catch 節(SpiderMonkey 拡張、JavaScript 1.5)。 |
ブラウザ実装状況
機能 | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
基本サポート | (有) | (有) | (有) | (有) | (有) |
条件付き catch (非標準) |
未サポート | (有) | 未サポート | 未サポート | 未サポート |
機能 | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
基本サポート | (有) | (有) | (有) | (有) | (有) | (有) |
条件付き catch (非標準) |
未サポート | 未サポート | (有) | 未サポート | 未サポート | 未サポート |