見出し画像

JavaScriptのエラー処理

コードがどれだけ完璧でも、想定外のユーザーが起こす行動や、ネットワークの不調など様々な要因でエラーが発生するかもしれません。エラーが起こると、たちまち正常に処理できなくなりスクリプトは止まってしまいます。

今回はエラーの対応に利用できるtry...catchをご紹介します。

try...catchの書き方

誰かがどうしようもなくなったとき無理という声が聞こえてくるかもしれません。聞こえてきたら、できるだけ助けたいように思います。

JavaScriptの世界では助けるためにtry...catchを使います。

try内でエラーが起こった場合、即座にcatchに処理が移ります。catchの処理が終わったとき、finallyが書かれていればそちらに移ります。

エラーが発生しない場合、catchの処理は実行されませんが、finallyの処理は実行されます。

try {
    // エラーが発生する可能性のある処理
} catch(err) {
    // エラー発生時の処理
} finally {
    // 正常時、エラー発生時両方で実行する処理
}

tryは必須ですが、catch、finallyはどちらか一つでも構いません。

ただ、finallyだけの場合エラーの情報が受け取れません。エラーが発生していた場合、finallyの処理終了後にエラーが発生します。

try {
} catch(err) {
    // エラー発生時の処理
}
try {
} finally {
    // 正常時、エラー発生時両方で実行する処理
}
// try処理内でエラーの場合ここでエラーが発生する

また、以下のように非同期で実行される場合はtry...catchもそちらの関数に書かなければ動作しません。

// NG
try {
    setTimeout(function() {
        // エラーが発生する可能性のある処理
    }, 1000);
} catch(err) {
    // エラー発生時の処理
}

// OK
setTimeout(function() {
    try {
        // エラー発生する可能性のある処理
    } catch(err) {
        // エラー発生時の処理
    }
}, 1000);

エラー発生時の情報

声を聞いて助けに行っても、何で困っているのかという状況を知らなければうまく助けられません。

そのような状況はcatchの後に書いてある引数のような変数に、オブジェクトとして格納されています。

try {
} catch(err) {
    console.log(err.name); // エラーの種類
    console.log(err.message); // エラーの内容
}

格納されるオブジェクトの種類として、Errorオブジェクト又は、Errorオブジェクトを継承したオブジェクトであることが多いです。

存在しない変数を参照しようとしたエラー時などに渡されるReferenceErrorやJSONファイルをオブジェクトに変換するときに文法のエラーなどで渡されるSyntaxErrorなど、さまざまな種類があります。

それらの主要なプロパティを紹介します。

name エラー名です。
message エラーの詳細が書かれた文字列です。
stack エラーを起こした関数がどこから呼ばれたのかに関する文字列です。

また、Errorオブジェクトを継承したオブジェクトを独自に定義することもできます。

エラーを出す

エラーは出したくないです。でも、そのまま進めて取り返しがつかなくなる前に、無理って声をあげましょう。具体的に何が無理か言えればもっといいですよね。なかなか難しいですが。

JavaScriptで無理と言うには以下のようにします。

throw new Error("muri");

throwの後にcatchに渡すオブジェクトを書きます。このオブジェクトには制限がありません。しかし、基本的にErrorオブジェクトやそれを継承したオブジェクトを渡します。

ErrorオブジェクトなどのJavaScriptに元々用意されたエラーオブジェクトは、コンストラクタで文字列を渡すと、messageプロパティに格納されます。

エラー処理をあきらめる

助けを求める声を聞いて駆けつけても、話を聞いてみると自分ではどうしようもない問題だったという場合、どうすればいいでしょうか。

JavaScriptではそういう場合、もう一度無理って言うことができます。

try {
    // エラー発生
} catch(err) {
    if(err instanceof SyntaxError) {
        // SyntaxErrorだった場合の対処
    } else {
        throw new Error("muri");
    }
}

こうすることで、この関数の呼び出し元はエラーが発生したということを知ることができます。

もし、コンソールに出力して終わりにすると、呼び出し元からは正常に動いたように見えてしまうかもしれません。

まとめ

JavaScriptの世界では助けれる状況の場合だけ助けて、それ以外は全部誰かに任せてしまうのがいいみたいです。

また、今回はエラーと表現しましたが、例外と呼ばれることもあります。

・エラーはtry...catchで処理できる
・エラーの情報はcatch(err)の変数errに入る
・throwでエラーを出せる。
・自分の責任でこなせることだけ行う。


この記事が参考になれば幸いです!