サーチ…


Node.Jsで例外を処理する

Node.jsには、例外/エラーを処理する3つの基本的な方法があります。

  1. try - catchブロック
  2. callbackへの最初の引数としてのエラー
  3. emit持つEventEmitterを使用してエラーイベントを

try-catchは、同期コードの実行からスローされた例外を捕捉するために使用されます。呼び出し元(または呼び出し元の呼び出し元など)がtry / catchを使用した場合、エラーをキャッチできます。呼び出し元のどれもtry-catchを持っていない場合、プログラムがクラッシュします。
非同期操作でtry-catchを使用していて、asyncメソッドのコールバックからtry-catchで捕捉されない例外がスローされた場合。非同期操作コールバックから例外をキャッチするには、 約束を使用することをお勧めします。
それをよりよく理解する例

// ** Example - 1  **
function doSomeSynchronousOperation(req, res) {
    if(req.body.username === ''){
        throw new Error('User Name cannot be empty');
    }  
    return true;  
}

// calling the method above
try {
    // synchronous code   
    doSomeSynchronousOperation(req, res)    
catch(e) {
    //exception handled here   
    console.log(e.message);  
} 

// ** Example - 2 **
function doSomeAsynchronousOperation(req, res, cb) {
    // imitating async operation
    return setTimeout(function(){
        cb(null, []);
    },1000);
}
 
try {
    // asynchronous code   
    doSomeAsynchronousOperation(req, res, function(err, rs){
        throw new Error("async operation exception");
    })   
} catch(e) {
     // Exception will not get handled here
     console.log(e.message);  
}
// The exception is unhandled and hence will cause application to break

コールバックは、イベントを非同期に配信するため、Node.jsで主に使用されます。ユーザーは関数(コールバック)を渡し、非同期操作が完了したときにいつか呼び出すことができます。
通常のパターンは、コールバックがコールバック(err、result)として呼び出され、操作が成功したか失敗したかに応じて、errおよびresultのいずれか一方のみがnullでないことです。

function doSomeAsynchronousOperation(req, res, callback) {
   setTimeout(function(){
        return callback(new Error('User Name cannot be empty'));    
   }, 1000);  
   return true;
}

doSomeAsynchronousOperation(req, res, function(err, result) {
   if (err) {
       //exception handled here 
       console.log(err.message);
   }
   
   //do some stuff with valid data
});

emitより複雑なケースでは、コールバックを使用する代わりに、関数自身がEventEmitterオブジェクトを返すことができ、呼び出し元はエミッタのエラーイベントをリスンすることが予想されます。

const EventEmitter = require('events');

function doSomeAsynchronousOperation(req, res) {
    let myEvent = new EventEmitter();

    // runs asynchronously
    setTimeout(function(){
        myEvent.emit('error', new Error('User Name cannot be empty'));
    }, 1000);

    return myEvent;
}

// Invoke the function
let event = doSomeAsynchronousOperation(req, res);

event.on('error', function(err) {
    console.log(err);
});

event.on('done', function(result) {
    console.log(result); // true
});

未手当ての例外管理

Node.jsは単一のプロセスで実行されるため、キャッチされない例外はアプリケーションの開発時に注意する必要があります。

静かに例外を処理する

大部分の人々は、node.jsサーバーがエラーを静かに飲み込ませるようにしています。

  • 例外を静かに処理する
process.on('uncaughtException', function (err) {
  console.log(err);
});

これは悪いですが 、それは動作しますが、

  • 根本的な原因は未知のままであるため、例外(エラー)を引き起こした原因の解決には役立ちません。

  • 何らかの理由でデータベース接続(プール)がクローズした場合、エラーが継続的に伝播します。つまり、サーバーは実行中ですが、dbに再接続しません。


初期状態に戻る

"uncaughtException"の場合は、サーバを再起動して初期状態に戻すと良いでしょう。そこでは動作することがわかっています。例外はログに記録され、アプリケーションは終了しますが、サーバーが稼働していることを確認するコンテナーで実行されるため、サーバーの再始動(最初の稼動状態への復帰)が行われます。

  • 永遠(または他のCLIツールをインストールして、ノードサーバーが継続的に稼働していることを確認する)
npm install forever -g
  • 永遠にサーバーを起動する
forever start app.js

理由はなぜそれが始まり、私たちが永遠に使用する理由は、サーバーが永遠に終了した後にプロセスがサーバーを再び開始するということです。

  • サーバーの再起動
process.on('uncaughtException', function (err) {
    console.log(err);

    // some logging mechanisam
    // ....        

    process.exit(1); // terminates process
});

また、 クラスタとドメインで例外を処理する方法もありました。

ドメインはここでは非難されています

エラーと約束

プロミスは、同期またはコールバック駆動のコードとは異なる方法でエラーを処理します。

const p = new Promise(function (resolve, reject) {
    reject(new Error('Oops'));
});

// anything that is `reject`ed inside a promise will be available through catch
// while a promise is rejected, `.then` will not be called
p
    .then(() => {
        console.log("won't be called");
    })
    .catch(e => {
        console.log(e.message); // output: Oops
    })
    // once the error is caught, execution flow resumes
    .then(() => {
        console.log('hello!'); // output: hello!
    });

現時点では、約束の中に投げ込まれたエラーが捕捉されず、エラーが飲み込まれ、エラーを追跡することが困難になる可能性があります。これは、 eslintのようなlintingツールを使うか、常にcatch節を持つようにすることで解決できます。

この動作は、ノードプロセスを終了するために、ノード8で推奨さなくなりました



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow