例外処理とは
例外というのは、エラー(ランタイムエラー)のことです。エラーが出るとそこでプログラムは強制終了してしまいます。
しかし、外部との通信やデータのやり取りをするようなプログラムは様々な要因によるエラーを避けることはできません。
そこで、JavaScriptやTypeScriptには、エラーを取り扱うための方法が用意されています。
throw文とErrorオブジェクト
throwというのは、「投げる」という意味です。throwで何かが投げられるとエラーが発生します。
const dog = "Hello";
throw dog;
console.log("world");
この例では、throwで変数dogを投げています。この時点でエラーが発生するのでプログラムは終了してconsole.logまで到達することはできません。throwに渡すのは、式なら何でも可能です。
そして、throwに渡すのは基本的にErrorオブジェクトを指定します。まずは、newを使ってErrorインスタンスを作成します。
Errorコンストラクタは、引数に文字列を指定することができ、その文字列がエラーメッセージとして扱われます。Errorインスタンスにはmessageプロパティがあり、これがエラーメッセージを表しています。なのでコンストラクタで文字列を指定してあげます。
const err = new Error("エラーが発生!!");
throw err;
現状だとエラーが発生したら強制的にそこでプログラムが止まってしまうのですが、そこで、エラーが発生してもプログラムを実行し続けるための機能が用意されています。
try-catch文
エラーが発生してもプログラムが強制終了しないようにするためには、try-catch文を使用します。最も基本的な形は次のように書きます。
try {
// tryブロック(文を複数記述できる)
} catch(err) {
// catchブロック(ここも文を記述できる)
}
このように2つのブロックからなり、try-catch文では、必ず{ }でブロックを用いなければいけません。catch (err)の部分に出てきているerrは変数名なので好きな名前を使用できます。
まずtryブロックの中の処理を実行し、tryブロックの中で例外が発生した場合にはcatchブロックを実行します。このとき、tyrブロックの処理は中断され、例外が発生した時点で即座にcatchブロックに移行します。catchというのは、throw(投げた)エラーを受け止めるというイメージです。throwによって投げられたErrorオブジェクトがcatchで宣言された変数errに代入されます。
try {
console.log("エラー発生させる");
throw new Error("エラー");
} catch (err) {
console.log("エラーキャッチした");
console.log(err);
}
console.log("終了");
これを実行すると、エラー発生させるという文字列とともにエラーをキャッチしたという文字列とエラー、終了と表示されるはずです。try-catch文を使うことでエラーが発生してもプログラムを中断することなく最後まで実行することができました。
ちなみに、今回はthrowで強制的にエラーを発生させましたが、throw以外の要因でエラーが発生する場合でもtry-catch文を使うことができます。次の例では変数bは存在しないでのエラーが発生しています。
try {
console.log("エラー発生させる");
console.log(b);
} catch (err) {
console.log("エラーキャッチした");
console.log(err);
}
console.log("終了");
finally
try-catch文の後ろにはさらにfinallyブロックを付け加えることができます。また、catchブロックを省略してtry-finallyという形にすることもできます。
try {
console.log("tryブロック");
} catch (err) {
console.log("catchブロック");
} finally {
console.log("finallyブロック");
}
finallyブロックは、エラーが発生してもしなくても実行されます。つまり、tryブロックを実行してエラーが発生しなかった場合は、次にfinallyブロックが実行されます。