JavaScript によるエラー処理

12月連続記事企画の6日目…あれ、おかしいですね。カレンダーが7日になっています。

まぁ、細かいことは気にせず記事を書きましょう。エラー処理について書いてみたいと思います。

Mutually Exclusive and Collectively Exhaustive

表示を止めないエラー処理を実装する上では、いわゆる「MECE」が重要です。

…などと話をすると、エラーの種類を事細かに挙げようとする人がいますが、それは上手くいきません。エラーを細かく分類して、以下のようなコードを書いてしまう人を時々見かけます。

try {
  // 例外が発生するかもしれない処理
} catch (e if e == "Error A") {
  // Error A の処理
} catch (e if e == "Error B") {
  // Error B の処理
} catch (e if e == "Error C") {
  // Error C の処理
}

"Error D" とか、他のエラーは絶対に発生しないのでしょうか。仮に今のコードで大丈夫だったとしても、将来的には誰かが "Error X" を発生させるかもしれません。コードを変えなくても、ブラウザのバージョンでエラーが違ってくるかもしれません。全てのエラーを特定するという考え方は、現実的ではありません。

現実にはエラーを細かく見るのとは別の考え方で、エラー処理の取りこぼしがない構造を実現する必要があります。

実際のエラー処理

昨日の記事で紹介した JavaScript には、通信エラーやサーバーのエラーに対応する処理が書かれていませんでした。エラー処理を追加してみましょう。

function update() {
    var req = [{ "method": "read", "addr": "ZR300", "len": 5 }];
    var param = { driver: "MELSEC-MX", station: 0, requests: req };
    try {
        var success = false;
        var xhr = new XMLHttpRequest();
        xhr.open("POST", "/api/plcComm", true);
        xhr.onload = function () {
            var res = JSON.parse(xhr.response).responses;
            // PLC のデータは配列になっている  例: [2017, 12, 7, 21, 17]
            if (Array.isArray(res[0].data) && res[0].data.length == req[0].len) {
                document.body.innerText = res[0].data.toString();
                success = true;
            }
        }
        xhr.onloadend = function () {
            if (!success) {
                display_error("通信エラー");
            }
            setTimeout(update, 50);
        }
        xhr.setRequestHeader("Content-Type", "application/json");
        xhr.timeout = 500;
        xhr.send(JSON.stringify(param));
    } catch (e) {
        display_error("XMLHttpRequestのエラー")
        setTimeout(update, 50);
    }
}

function display_error(message) {
    document.body.innerText = message;
}

document.addEventListener("DOMContentLoaded", function () {
    update(); // 画面の更新を開始する
});
  • 処理が成功した場合を success = true として、それ以外の時をエラーとしています。
  • 例外が発生する処理を try ... catch で処理しています。

上記の実装であれば、一時的にサーバーエラーやネットワークエラーが発生した場に合はエラー表示をして、エラー状態から回復した時にはデータが表示されるはずです。ところで…

PLC で単純な数値以外の情報を扱いたい場合にはどうしたらいいのでしょうか。
明日は PLC のデータ構造について書いてみたいと思います。

この記事の投稿者

崎 洋佑
崎 洋佑プログラマーもどき
さきラボの代表取締役。自称プログラマーもどき。
開発でよく使う言語は日本語。
IT技術よりも人が好きな、天然物のエンジニアです。
PLC のデータ型