try...catch
BaselineWidely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
try...catch
文はtry
ブロックと、catch
ブロックかfinally
ブロックか、その両方から構成されます。まずtry
ブロック内のコードが実行され、そこで例外が発生すると、catch
ブロック内のコードが実行されます。finally
ブロック内のコードは、制御する流れが構造全体を抜ける前に、常に実行されます。
試してみましょう
try { nonExistentFunction();} catch (error) { console.error(error); // Expected output: ReferenceError: nonExistentFunction is not defined // (Note: the exact output may be browser-dependent)}
構文
try { tryStatements} catch (exceptionVar) { catchStatements} finally { finallyStatements}
tryStatements
実行される文です。
catchStatements
try
ブロックの中で例外が発生した場合に実行される文です。exceptionVar
省略可関連する
catch
ブロックが捕捉した例外を保持するためのオプションの識別子です。もしcatch
ブロックが例外の値を利用しない場合は、exceptionVar
とその周りの括弧を省略してcatch {...}
のようにすることができます。finallyStatements
try...catch...finally
構造から制御フローが脱出する前に実行される文です。これらの文は、例外が発生されたり捕捉されたりしたかどうかに関係なく実行されます。
解説
try
文は、常にtry
ブロックから始まります。それから、catch
ブロックまたはfinally
ブロックが存在する必要があります。catch
およびfinally
ブロックが両方存在しても構いません。すなわち、try
文には 3 つの形態があります。
try...catch
try...finally
try...catch...finally
if
やfor
などの他の構造とは異なり、try
、catch
、finally
の各ブロックは単一の文ではなく、ブロックでなければなりません。
try doSomething(); // SyntaxErrorcatch (e) console.log(e);
catch
ブロックは、例外がtry
ブロックの中で発生した場合に何をするかを指定する文を含みます。try
ブロック内(またはtry
ブロック内から呼び出された関数の中)のいずれかの文で例外が発生した場合は、制御は即座にcatch
ブロックへ移ります。try
ブロックの中で例外が発生しなかった場合は、catch
ブロックは飛ばされます。
finally
ブロックは、制御フローがtry...catch...finally
構造から脱出する前に常に実行されます。これは常に実行され、例外が発生したかどうか、捕捉されたかどうかには関係ありません。
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
ブロックの中で発生したときは、exceptionVar
(たとえば、catch (e)
におけるe
)が例外の値を保持します。この識別子を使用して、発生した例外についての情報を取得することができます。この識別子はcatch
ブロックのスコープでのみ利用できます。例外の値が必要ない場合にはこれは省略できます。
function isValidJSON(text) { try { JSON.parse(text); return true; } catch { return false; }}
finally ブロック
finally
ブロックには、try
ブロックおよびcatch
ブロックを実行した後で、try...catch...finally
の次の文が実行される前に実行される文が入ります。制御フローは以下のいずれかの場面で、常にfinally
ブロックに入ります。
try
ブロックが正常に(例外が発生せずに)終了する直前catch
ブロックの実行が正常に終了する直前- 制御フロー文(
return
、throw
、break
、continue
)がtry
ブロックやcatch
ブロックの中で実行される直前
なお、finally
ブロックは例外が発生するかどうかにかかわらず実行されます。また、例外が発生した場合、finally
ブロックは例外を処理するcatch
ブロックがなくても実行されます。
次の例ではfinally
ブロックの一つの使用例を示します。このコードはファイルを開き、それからファイルを使用する分を実行します。finally
ブロックは、例外が発生したとしてもその後で確実にファイルを閉じるよう保証します。
openMyFile();try { // リソースを結び付けます writeMyFile(theData);} finally { closeMyFile(); // リソースを常に閉じます}
制御フロー文(return
,throw
,break
,continue
)をfinally
ブロック内で使うと、try
ブロックやcatch
ブロックの完了値を「マスク」します。この例では、try
ブロックは 1 を返そうとしますが、返す前にまずfinally
ブロックに制御を委ねるので、代わりにfinally
ブロックの返値が返されます。
function doIt() { try { return 1; } finally { return 2; }}doIt(); // returns 2
一般に、finally
ブロックの中に制御フロー文を置くのは悪い考えです。クリーンアップのためのコードのみを使用してください。
例
入れ子になった 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
ブロック内で例外が発生した場合も含まれます。
(() => { 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® 2026 Language Specification # sec-try-statement |