try...catch
try...catch
文は、試す文のブロックをマークし、例外が発生したときの応答を指定します。
試してみましょう
構文
try {
try_statements
}
catch (exception_var) {
catch_statements
}
finally {
finally_statements
}
try_statements
-
実行される文です。
catch_statements
-
try
ブロックの中で例外が発生した場合に実行される文です。 exception_var
-
関連する
catch
節に対して例外オブジェクトを保持する識別子です。 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);
}
// Output:
// "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);
}
// 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
ブロックで一度だけ捕捉されます。もちろん、何らかの例外が「内側の」のブロックで発生した場合 (catch
ブロックのコードで例外が発生することを行った場合)、「外側の」ブロックで捕捉されます。
finally ブロックからの return
finally
ブロックが値を返す場合、その値が try-catch-finally
全体の返値になり、 try
ブロックや catch
ブロックの return
文に関係なくなります。
これは 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);
}
})();
// 出力結果:
// "inner" "oops"
// "finally"
外側の "oops" は finally
ブロックに return があるため送出されません。同じことが、catch
ブロックから返されているそのほかの値にも適用されます。
仕様書
Specification |
---|
ECMAScript Language Specification # sec-try-statement |
ブラウザーの互換性
BCD tables only load in the browser