Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

  1. トップページ
  2. JavaScript応用編 - try...catch文(例外処理)の使い方

try...catch文(例外処理)の使い方

みなさまどうも。

続きまして『throw文』(スローぶん)と『try文』(トライぶん)と『catch文』(キャッチぶん)と『finally文』(ファイナリーぶん)の解説です。『try文』と『catch文』と『finally文』はまとめて『try...catch文』、または『try/catch文』などと呼ばれることが多いですね。

これらは『例外』、つまりエラーとか想定外の事態が発生した時の対処用に用意されている処理といった感じです。想定外の事態に特化しているので細かいエラー情報が知れたり、エラーが出てもそのまま処理を止めずに継続できるような設計にしたり、といった事ができます。

プログラミングにおける『例外』とはコンピューターが通常の処理として想定していないような事態全てを指すような言葉です。まあ、エラーとか想定外の処理が走ってしまうとか、そういう全ての事象を指す言葉として認識してしまってOKです。

なので「ここの処理って『例外処理』入れてる?」と現場の先輩とかに聞かれたら「エラーが出た時や、想定外の処理が走ったりしたときとかの対応をちゃんと考えてコーディングしているか?」と質問されてるものとして脳内変換しちゃって下さい。

あと『throw』は「投げる」という意味なので、「例外を出す」とか「例外を発生させる」じゃなくて「例外を投げる」と表現されることが多いです。こちらもご注意です。

さて、早速でございますが他の言語の『throw文』と『try...catch文』はまあまあ使用される構文です。しかし、JavaScriptにおいてはあんまり使われません。

というのも、JavaScriptは基本的にブラウザ上で動かす言語なので、処理の流れが目で確認できるような状態になっていることが多いです。

しかも最近のほぼ全てのブラウザは開発ツール機能を標準で搭載しているので、全てにエラー情報の出力処理が入っているような状態です。なので特に例外対応に思いを馳せなくてもエラー箇所の特定が容易なんですよね。あと漠然としたエラーではなく起こりそうな事態を絞り込んで対策を行った方がベターであるという理由もあったりします。

他の言語の場合、例えば24時間自動で好きな女の子のなんらかの画像を集めてくれる処理を書いてデーモンプロセス(バックグラウンドで実行してくれる常駐アプリケーションみたいなもの)で実行させるすると、処理結果やエラーを出力してくれる画面などがないため、何らかのトラブルが発生してもすぐに気づくことができません。

そういう時に『try...catch文』を使用して処理の状態をメールで報告するように仕込んだりすることでささっと何らかの対応ができるようになります。

こんな感じで他の言語とJavaScriptでは特性が違いすぎるため、この記事はざっと流し読みするくらいで十分かもしれません。そこはご了承下さい。

さて、前座が長くなりましたが改めてやっていきましょう。まずは『throw文』からです。これは例外を投げる文、つまり強制的に例外(エラー)が出ているような状態にする処理です。書き方は以下のような感じです。とっても簡単です。

throw "お好きなデータ";

『throw』と記述し、その右に半角スペースとかをおいて、その横にぶん投げたいお好きなデータを記述します。上記のサンプルをgoogle chromeで実行させると以下の文字列がコンソール画面に出力されます。

Uncaught お好きなデータ

このサンプルでは文字列『お好きなデータ』と記述しましたが、JavaScriptの『throw文』で送り返すデータには型の制限がないため、どんな値でもぶん投げることができます。

なので例外が発生したときの報告方法は自由に決めることが可能です。エラー内容を数値で管理してそれを報告するもよし、以下のようにエラーを日本語で報告するようにしちゃってもOKです。

throw {
    errorNum: 1,
    errorMessage: "ググレカス"
};
Uncaught Object {errorNum: 1, errorMessage: "ググレカス"}

尚、他の言語では『終了ステータス』という概念がありプログラムが正常終了した時には数値『0』を出力したりするので、数値『0』だったらエラー無し、他の数値だったら何らかのエラー、といった設計にするのも良いかもしれませんね。

ちなみに『throw文』では何かを投げないとNGなので注意して下さい。

throw; // 何かを投げないとダメです。

あとJavaScriptにはエラー用のオブジェクト、『Errorオブジェクト』が用意されています。これはエラーを報告するためのオブジェクトなので『throw文』を使用するときにセットで使われることが多いです。あと最近のブラウザでは何かバグ等を出した時とかに、その内容を親切にコンソール画面で教えてくれたりするわけなんですが、あの処理も実は『Errorオブジェクト』が使われていたりします。

というわけで『Errorオブジェクト』の使い方は以下みたいな感じですね。『new演算子』の隣に『Error()』を書けばOKです。

throw new Error();

実行させるとこうなります。

Uncaught Error(…)

何かメッセージを出力させたい場合は『Error()』の引数に渡してあげればOKです。

throw new Error("ググレカス");
Uncaught Error: ググレカス(…)

さてこちらの『Errorオブジェクト』でございますが、こちらもあんまり使用されることはないです。一応、例外内容に合わせた処理を構築したりすることもできるんですが、ほぼ全て『if文』とかで代用可能なのでわざわざ『Errorオブジェクト』で構築する方はあんまりいなかったりします。まあこの辺はお好みでどうぞ。

さて、例外を投げることができるのは分かったのですが「『console.log()』とかと何が違うの?」と思った方多いと思います。

違いをあげるとするならば『throw文』は『例外』を投げている、つまり想定外の状態になっている状態を作り出しているのでプログラムがそこで停止します。

throw 1; // ここでプログラムは停止します。
console.log(true); // ここは実行されません。

とはいっても、なんだか使い道がイマイチわからないですね。

そこで使うのが『try...catch文』です。『try...catch文』を使用すると例外が発生した場合の動作を設計することができます。以下のサンプルを見て下さい。

try{
    throw 1;
}
catch(e){
    // ここに処理。
}
finally{
    // ここに処理。
}

『try文』と『catch文』と『finally文』が使用されてますね。記述方法は『try』、『catch』または『finally』と記述したあとに『{}』を記述してその中に処理を書けばOKです。

注意点として『if文』などのように処理の内容が1行だった場合でも『{}』の省略はできません。必ず『{}』を記述するようにして下さい。あと『catch文』のみ『(e)』が必要です。『e』という文字はお好きな文字(JavaScriptで定義できる変数名)に変更することができますが『e』という文字が使用される事が多いです。

あと『try文』を記述するならば『catch文』か『finally文』のどちらか1つ以上を必ず記述しないといけません。んでもって『catch文』は複数記述することができたりします。ここちょっと間違いやすいので注意して下さい。

try{ // これは『catch文』か『finally文』がないのでエラーです。
    throw 1;
}

try{ // これはOKです。
    throw 1;
}
catch(e){
    // ここに処理。
}
finally{
    // ここに処理。
}

try{ // これはOKです。
    throw 1;
}
catch(e){
    // ここに処理。
}

try{ // これはOKです。
    throw 1;
}
catch(e){
    // ここに処理。
}
catch(e){
    // ここに処理。
}
catch(e){
    // ここに処理。
}

try{ // これはOKです。
    throw 1;
}
finally{
    // ここに処理。
}

続いて使い方です。まず例外が発生しそうな処理を『try文』の中に書きます。

try{
    // ここに例外が発生しそうな処理を書きます。
}

例外が発生した時に実行したい処理を『catch文』に記述します。

try{
    // ここに例外が発生しそうな処理を書きます。
}
catch(e){
    // 例外が発生したときに実行したい処理を書きます。
}

んでもって例外が発生しようとしなかろうと必ず実行したい処理があれば『finally文』に書きます。

try{
    // ここに例外が発生しそうな処理を書きます。
}
catch(e){
    // 例外が発生したときに実行したい処理を書きます。
}
finally{
    // 例外が発生しようとしなかろうと必ず実行したい処理があればここに書きます。
}

基本的にはこれだけです。

ではちょっと試してみましょう。以下のサンプルを見て下さい。

初音ミク;
console.log(true);

いきなり『初音ミク』と記述してみました。JavaScriptは内部的にUnicode文字が使用されているので日本語も使えちゃったりするのですが、『初音ミク』は何も定義してないので実行させるとこんな文字がコンソール画面(google chrome)に出力されます。

Uncaught ReferenceError: 初音ミク is not defined(…)

はい、バッチリ例外が出てますね。『初音ミク』のところで例外が出てるため続く処理の『console.log(true)』が実行されてません。

これに『try...catch文』を使ってあげるとあら不思議。

try{
    初音ミク;
}
catch(e){

}
finally{

}

console.log(true);
true

『初音ミク』のところで例外が発生しているにも関わらず続く処理(『console.log(true)』)が実行されてますね。

そして例外が発生したときに行いたい処理を『catch文』に記述します。文字列『アンビリカルケーブル断線!活動限界まであと5分です!』を出力するならばこういう感じです。

try{
    初音ミク;
}
catch(e){
    console.log("アンビリカルケーブル断線!活動限界まであと5分です!");
}

console.log(true);
アンビリカルケーブル断線!活動限界まであと5分です!
true

そして『catch文』の第1引数みたいなところに記述した『e』に注目です。JavaScriptではここに例外内容を入れてくれる構造になっているのでこれを出力してあげると調子よいです。ちょっと試してみましょう。こんな感じですね。

try{
    初音ミク;
}
catch(e){
    console.log(e);
}
finally{

}

console.log(true);

実行させるとこうなります。

ReferenceError: 初音ミク is not defined(…)
true

英語ですが「定義されてないっすよー!」と教えてくれてますね。

そして『catch文』でJavaScriptの処理を停止したい、といった場合は『throw文』を使用します。JavaScriptには他の言語に用意されている、処理を停止させるための『exit()』や『die()』が用意されてないのでこの方法がよく使用されますね。ここでも『e』を投げてあげると調子よいかもしれません。

try{
    初音ミク;
}
catch(e){
    throw e; // 『throw文』で『e』を投げます。処理がここで停止します。
}
finally{

}

console.log(true); // ここは実行されません。
Uncaught ReferenceError: 初音ミク is not defined(…)

そして、例外が発生しようとしなかろうと必ず実行したい処理があれば『finally文』に書いてあげればOKです。『catch文』で『throw文』を使用していても『finally文』に記載された処理は停止することなく実行してくれますので覚えておきましょう。

try{
    初音ミク;
}
catch(e){
    throw e; // 『throw文』で『e』を投げます。処理がここで停止します。
}
finally{
    console.log("『finally文』だよー!");
    console.log("『catch文』で『throw文』使っても実行されるよー!");
}

console.log(true); // ここは実行されません。
『finally文』だよー!
『catch文』で『throw文』使っても実行されるよー!
Uncaught ReferenceError: 初音ミク is not defined(…)

というわけで以上になりますね。基本的に「変な事態が発生しても他の処理は継続させたい」といった目的で使用されることが多いですが、JavaScriptおいての使用頻度はそこまで高くありません。ただ、他の言語では良く使用されるので仕組みだけでも理解しておくと良いかもしれません。

続いての記事では型の判定について色々とやっていきましょう。ではこの辺で失礼致します。

この記事は桜舞が執筆致しました。

著者が愛する小型哺乳類

桜舞 春人 Sakurama Haruto

ISDN時代から様々なコンテンツを制作しているちょっと髪の毛が心配な東京在住のプログラマー。生粋のロングスリーパーで、10時間以上睡眠を取らないと基本的に体調が悪い。好きなだけ寝れる生活を送るのが夢。ゲームとスポーツと音楽が大好き。誰か髪の毛を分けて下さい。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。