Core JavaScript 1.5 Guide:Exception Handling Statements:try...catch Statement
出典: MDC
目次 |
[編集] try...catch 文
try...catch 文はテストしたい文のブロックを指定し、さらに投げられるであろう例外に対する 1 つ以上の対処方法を指定します。例外が投げられると try...catch 文がそれを受け取ります。
try...catch 文は 1 つの try ブロックと 0 個以上の catch ブロックからなります。前者は 1 つ以上の文からなります。後者は try ブロックで例外が投げられた場合にどうするかを指定する文からなります。すなわち、成功させたい try ブロックと、失敗した場合にコントロールを渡す catch ブロックからなります。try ブロック内(もしくは try ブロック内から呼び出された関数内)のいずれかの文が例外を投げた場合、コントロールはすぐに catch ブロックに移ります。try ブロックで例外が投げられなかった場合は catch ブロックは飛ばされます。finally ブロックは try および catch ブロックが実行された後に実行されます。ただし try...catch 文の後に続く文より先に実行されます。
次の例では try...catch 文を使用しています。この例では渡された値に基づいて配列から月の名前を取り出す関数を呼び出します。値に対応する月の数字 (1-12) がなかったら、InvalidMonthNo という値を持つ例外が投げられ、catch ブロックの中の文は monthName という変数に unknown という値をセットします。
function getMonthName (mo) {
mo=mo-1; // 月の数字を配列のインデックスに合わせる (1=Jan, 12=Dec)
var months=new Array("Jan","Feb","Mar","Apr","May","Jun","Jul",
"Aug","Sep","Oct","Nov","Dec");
if (months[mo] != null) {
return months[mo]
} else {
throw "InvalidMonthNo"
}
}
try {
// テストする文
monthName=getMonthName(myMonth) // 関数は例外を投げることがある
}
catch (e) {
monthName="unknown"
logMyErrors(e) // 例外オブジェクトをエラー処理部分に渡す
}
[編集] catch ブロック
単一の catch ブロックを使用すると、try ブロックで生じうるすべての例外を扱うことができます。また、扱う例外の種類によって catch ブロックをそれぞれに分けることもできます。
単一の catch ブロック
try ブロックで投げられるいかなる例外にも対応したエラー処理コードを実行するには、try...catch 文で catch を 1 つ使用してください。
単一の catch ブロックは次のように使用します。
catch (catchID) {
statements
}
catch ブロックは、throw 文で指定された値を持つ識別子(上記の構文における catchID)を指定します。この識別子を使用することで投げられた例外についての情報を得ることができます。JavaScript は catch ブロックに入るときにこの識別子を作成します。識別子は catch ブロックにいる間だけ持続します。つまり、catch ブロックの実行が終了するとその識別子はもう使えなくなります。
例えば、次のコードは例外を投げます。例外が生じるとコントロールが catch ブロックに移ります。
try {
throw "myException" // 例外を生成
}
catch (e) {
// どんな例外も扱う文
logMyErrors(e) // 例外オブジェクトをエラー処理部分に渡す
}
複数の catch ブロック
1 つの try 文に対して、複数の条件についての catch ブロックを使うことができます。そして、そのそれぞれがそれぞれの種類の例外を担当します。この場合、そのブロックで指定されている例外が投げられたときだけ、適切な条件の catch ブロックに入ることになります。すべての未指定の例外のために、すべての例外に対応した catch ブロックをその文の最後の catch ブロックとしてオプション的に設けることもできます。
例えば、次の関数は 3 つの別の関数(どこかで定義済み)を呼び出します。この関数はその引数が妥当であるかを確かめます。妥当性確認関数が確認対象の構成要素が妥当でないと決定した場合、その関数は 0 を返し、該当する例外を呼び出し元に投げさせます。
function getCustInfo(name, id, email)
{
var n, i, e;
if (!validate_name(name))
throw "InvalidNameException"
else
n = name;
if (!validate_id(id))
throw "InvalidIdException"
else
i = id;
if (!validate_email(email))
throw "InvalidEmailException"
else
e = email;
cust = (n + " " + i + " " + e);
return (cust);
}
おのおのの条件の catch ブロックは適当な例外処理部分にコントロールを渡します。
try {
// 関数は 3 つの例外を投げうる
getCustInfo("Lee", 1234, "lee@netscape.com")
}
catch (e if e == "InvalidNameException") {
// 不正な名前に対しての処理部分を呼び出す
bad_name_handler(e)
}
catch (e if e == "InvalidIdException") {
// 不正な ID に対しての処理部分を呼び出す
bad_id_handler(e)
}
catch (e if e == "InvalidEmailException") {
// 不正なメールアドレスに対しての処理部分を呼び出す
bad_email_handler(e)
}
catch (e){
// 何が起きるかはわからないが、そのログをとる
logError(e)
}
[編集] finally ブロック
finally ブロックは、try および catch ブロックの実行が終わった後に実行される文からなります。ただし try...catch 文の後に続く文より前に実行されます。finally ブロックは例外が投げられても投げられなくても実行されます。例外が投げられた場合、finally ブロック内の文はたとえ例外処理をする catch ブロックがなくても実行されます。
finally ブロックを使用することで、例外発生時に適切にスクリプトを停止させることができます。例えば、スクリプトで使用していたリソースを解放する必要があるかもしれません。次の例ではファイルを開き、そのファイルを使用する文を実行します(サーバサイド JavaScript ではファイルにアクセスできます)。ファイルを開いている間に例外が投げられると、スクリプトが停止する前に finally ブロックがそのファイルを閉じます。
openMyFile();
try {
writeMyFile(theData); // エラーを投げる可能性がある
}catch(e){
handleError(e); // エラーを受け取り、それを処理する
}finally {
closeMyFile(); // 常にリソースを閉じる
}
[編集] try...catch 文のネスト
1 つ以上の try...catch 文を入れ子にすることができます。内側の try...catch 文に catch ブロックがない場合、囲んでいる try...catch 文の catch ブロックがマッチしているか確認されます。