プログラミングBlog

JavaScript 非同期同期 例外処理

実行環境

Node - v 14.16.0

例外の基本

try{}で囲ってる箇所に例外が起こりえるような処理を書いて、 もし例外が発生したらcatch{}の中に書いた処理を実行する。
finallyは実行してほしいような処理がある場合使う。

try {
    // 例外が発生するかもしれない処理
} catch (error) {
    // 例外発生時の処理
} finally {
    // 必ず実行される処理
}

例外の基本の書き方ですが、ファイルを読込処理をしていた時に 例外が拾えずはまったのでもう一度復習。

コールバックについて

非同期

ファイルを読み込むためにfsモジュールを使います。

const fs = require('fs');

fs.readFile('./saplme.txt');

このままだとエラーとなります。
TypeError [ERR_INVALID_CALLBACK]: Callback must be a function. Received undefined
仕様が変更されてfsモジュール使用時にコールバック関数がMustになっているため追加します。

const fs = require('fs');

fs.readFile('./sample.txt', (error, txt) => {
    if (error) {
        console.log(error);
    } else {
        console.log(txt.toString());
    }
});

第一引数はerrorが起こった場合、エラーオブジェクトが入ります。
第二引数は読み込めた場合、読み込んだ内容が入ります。
無事にtxtファイルの中身sampleが表示されました。

sample!

次にtrycatchで囲んだ後に例外を発生させてみましょう。
先ほどのsample.txtを削除して読み込めなくします。
その後にthrowでcatchさせるようにします。

テキストファイルが読み込めなかった場合。

const fs = require('fs');

try {
    fs.readFile('./sample.txt', (error, txt) => {
        if (error) {
            console.log('callback');
            throw error.message;
        } else {
            console.log(txt.toString());
        }
    });
} catch (err) {
    console.log('catch');
    console.log(err.message);
}
callback  
ENOENT: no such file or directory, open 'C:\repos\javasc\sample.txt'
(Use `node --trace-uncaught ...` to show where the exception was thrown)

結果からわかるようにコールバック関数を用いたエラーハンドリングでは、trycatchを外側に書くと拾うことはできないようです。
次はコールバック関数の中でtrycatchで拾うようにしてみます。

const fs = require('fs');

try {
    fs.readFile('./sample.txt', (error, txt) => {
        try{
        if (error) {
            console.log('callback');
            throw error;
        } else {
            console.log(txt.toString());
        }
    }catch(innnerError){
        console.log("innnerCatch")
        console.log(innnerError.message);
    }
    });
} catch (err) {
    console.log('catch');
    console.log(err.message);
}

無事拾うことができました。
可読性がひどいのでtrycatchではなくコールバック関数でエラーハンドリングすべきですね!

callback
innnerCatch
ENOENT: no such file or directory, open 'C:\repos\javasc\sample.txt'

同期

const fs = require('fs');

try {
    var txt = fs.readFileSync('./sample.txt');
    console.log(txt.toString());
} catch (err) {
    console.log(err.message);
}

trycatchは同期的に動くため、同期処理の場合はcatchできるようです。

catch
ENOENT: no such file or directory, open './sample.txt'

結論

  • 非同期の場合はコールバック関数でのエラーハンドリング
  • 同期の場合はtrycatchでのエラーハンドリング