Node.jsとExpressにアプリがあります。テストを書く必要があります。 Expressアプリのエラーの処理に問題があります。私はこれを見つけました EADDRINUSEのようなnode.js/expressサーバーエラーをキャッチするにはどうすればよいですか? 、しかしそれは私にとってはうまくいきません、理由はわかりません。 expressApp.listen()の実行中に発生する可能性のあるエラー(EADDRINUSE、EACCESなど)を処理したいと思います。
express = require('express')
listener = express()
#doesn't work for me
listener.on('uncaughtException', (err) ->
#do something
)
#doesn't work too
listener.on("error", (err) ->
#do something
)
#this works, but it caughts all errors in process, I want only in listener
process.on('uncaughtException', (err) ->
#do something
)
listener.listen(80) #for example 80 to get error
何か案は?
まず、expressJSはuncaughtException
イベントをスローしませんが、プロセスはスローします。そのため、コードが機能しないのは当然です。
したがって、代わりにprocess.on('uncaughtException',handler)
を使用してください。
次に、expressJSは、次のように、この目的のために提供するミドルウェア関数を使用するという、エラー処理の標準的な手段をすでに提供しています。
app.configure(function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
この関数は、オプションのスタックトレースを使用してエラーメッセージをクライアントに返します。これについては、 connectJS errorHandler に記載されています。
(errorHandlerは実際にはconnectJSの一部であり、expressJSによってのみ公開されることに注意してください。)
既存のerrorHandlerが提供する動作がニーズに十分でない場合、そのソースは connectJSのerrorHandler
ミドルウェア にあり、ニーズに合わせて簡単に変更できます。
もちろん、この関数を直接変更するのではなく、これを行う「正しい」方法は、次のように、connectJSバージョンを開始点として使用して独自のerrorHandlerを作成することです。
var myErrorHandler = function(err, req, res, next){
...
// note, using the typical middleware pattern, we'd call next() here, but
// since this handler is a "provider", i.e. it terminates the request, we
// do not.
};
そして、次のようにexpressJSにインストールします。
app.configure(function(){
app.use(myErrorHandler);
});
ConnectJSのfilter
およびprovider
ミドルウェアの考え方の説明については、 Just Connect it、Already および Connect/Express用のミドルウェアの書き方 を参照してください。よく書かれたチュートリアルのために。
また、これらが役立つ場合があります。
最後に、expressJSのテストに関する優れた情報源は、 独自のテスト にあります。
これでうまくいくはずです:
listener.listen(80).on('error', function(err) { });
何 listener.listen
実際には、HTTPサーバーを作成し、そのサーバーでlistenを呼び出します。
app.listen = function(){
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
言及:Marius Tibeica回答は完全で素晴らしいです、またdavid_pコメントは。 Rob Raischの答えもそうです(探索するのは興味深いです)。 https://stackoverflow.com/a/27040451/7668448
https://stackoverflow.com/a/13326769/7668448
これが便利だと思う人のために、ここではビジーポート処理を実装する関数です(ポートがビジーの場合、ビジーポートがなくなるまで次のポートで試行します)
app.portNumber = 4000;
function listen(port) {
app.portNumber = port;
app.listen(port, () => {
console.log("server is running on port :" + app.portNumber);
}).on('error', function (err) {
if(err.errno === 'EADDRINUSE') {
console.log(`----- Port ${port} is busy, trying with port ${port + 1} -----`);
listen(port + 1)
} else {
console.log(err);
}
});
}
listen(app.portNumber);
関数listenは、それ自体を再帰的に呼び出しています。ポートビジーエラーの場合。毎回ポート番号をインクリメントします。