質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

Q&A

解決済

3回答

3855閲覧

node.jsの例外処理について

退会済みユーザー

退会済みユーザー

総合スコア0

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

0グッド

0クリップ

投稿2018/06/11 21:43

ご覧いただきありがとうございます。
node.js×Expressでローカルでサーバーを構築しています。
エラー処理についてお伺いしたいのですが、
node.jsでは例外発生時に、例外処理を記述しないとサーバーが落ちてしまうと色々なサイトで知りました。

javascript

1//app.js 2var IndexPage = require('./routes/index.js'); 3var dbSettings = require(__dirname+'/settings/mongo_setting.js'); 4 5 6process.on('uncaughtException', function (err) { 7 console.log('uncaughtException => ' + err); 8}); 9 10app.get('/',IndexPage.index);

javascript

1//index.js 2var MongoClient = require('mongodb').MongoClient; 3var dbSettings = require('../settings/mongo_setting.js'); 4 5exports.index = function(req,res){ 6 MongoCliant.connect(dbSettings.dbUrl,(err,database)=>{ 7 try{ 8 const myDB = database.db(dbSettings.dbName); 9 //以下I/O処理 10 }catch(e){ 11  console.log(e); 12 res.render('../views/Erro.ejs'); 13 }; 14 }); 15};

javascript

1//mongo_settings.js 2exports.dbUrl = "mongodb://localhost"; 3exports.dbName = "test";

I/O処理に負荷をかけた際に起きるエラーが
TypeError: Cannot read property 'db' of nullと表示されます。
trycatchでログを残して、エラーページに飛ばせてはいるのですが、その後アクセスしてもエラーページしか表示されず、ログには同じエラーが表示されています。
エラーを放置せずにtrycatchで受けてあげればサーバーは落ちないというのを教本で読み試してみました。
確かに、サーバー自体は落ちていないのですが、ページをリロードしてもエラーページが表示されたままです。
エラー処理の方法を大きく勘違いしているような気がしてなりません。
もしよろしければ教えていただければ幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

connectのみをしclose処理をしていないためmongodbの最大同時接続数に到達し、それ以上は接続できないためエラーが発生しているのではないでしょうか?

close処理を入れるか、connectしたobjectを使い回す(singleton)ようにすればエラーを回避することができると思いますよ。

追記

基本的な使い方まマニュアルに載ってますね。

https://docs.mongodb.com/manual/tutorial/atlas-free-tier-setup/

ts

1var MongoClient = require('mongodb').MongoClient; 2 3var uri = "mongodb://user123:p455w0rd@gettingstarted-shard-00-00-hyjsm.mongodb.net:27017,gettingstarted-shard-00-01-hyjsm.mongodb.net:27017,gettingstarted-shard-00-02-hyjsm.mongodb.net:27017/test?ssl=true&replicaSet=GettingStarted-shard-0&authSource=admin"; 4MongoClient.connect(uri, function(err, db) { 5 // Paste the following examples here 6 7 db.close(); 8});

この場合最後のコールバック関数時(res.render)に、myDB.close()とすれば一括で閉じることはできるのでしょうか?

catchでエラーページに飛ぶときのみcloseしても正常時にはcloseしないことになるのでfinallyが妥当です。

ts

1 }catch(e){ 2  console.log(e); 3 res.render('../views/Erro.ejs'); 4 } finally { 5 database.close(); // ←こっち 6 };

投稿2018/06/12 02:20

編集2018/06/12 07:17
mosapride

総合スコア1480

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/06/12 04:46

ご回答いただきありがとうございます。 重ねて質問になってしまい大変申し訳ないのですが、 I/O処理の部分で、複数のコレクションを参照(してtoArrayで引き出しています)してデータを取得しています。 この場合最後のコールバック関数時(res.render)に、myDB.close()とすれば一括で閉じることはできるのでしょうか?それともそれぞれのコレクション参照時にclose処理が必要なのでしょうか? 無知で申し訳ありません。
mosapride

2018/06/12 07:17

回答に追記しました。
退会済みユーザー

退会済みユーザー

2018/06/12 09:22

マニュアルの参照ありがとうございます。もう一度見直してみます。 また詳しくご回答頂き本当にありがとうございました。 すごくわかりやすく、本当に助かりました。
guest

0

connect() 何度も実行しているのに close() を行っていないために、何かの内部リソース(MongoClient内部のコネクションプールやNode.jsの既定のファイルディスクリプタの最大数に到達など)が枯渇しているのではないかというtenpaさんの意見に同意します。

その上での話ですが MongoClient.connect() のコールバック関数の冒頭(database.db()をコールする直前)で err が null であることを確認したらどうでしょうか?

接続エラー発生時には err にエラーの内容を示すメッセージ文字列が入りますので、それを見ると問題が具体的になると思います。

あと、connect() のコールバック関数の第二引数(変数名 database)はそれ自体がDbオブジェクトなので、複数のカーソルを使うのでなければ、database.db() の呼び出しは不要です。

ご参考になれば。

投稿2018/06/12 03:05

tkanda

総合スコア2425

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/06/12 04:55

ご回答いただきありがとうございます。 connect()のご指摘いただき、リファレンス等読み返したところ、 dbUrl = "mongodb://localhost:27017/<データベース名>としていてtkanda様のご指摘どおりでした。 自分も早速、"mongodb://localhost:27017/test"と書き換えてみたのですが、collection of nullのエラーが発生してしまい、データベースに正しくアクセスできないようです。 何分サーバーサイドに不慣れなもので、dotinstallをみてローカルサーバーに言われるがままインストールしたのでその際に何か設定漏れ?のようなものがあったのかもしれません。 もう一度見直してみます。
guest

0

まず第一に、同じ処理でもIOに負荷がかかる時とかからない時があるのでしょうか?
失敗するような動作を反復しているのであれば、例外処理をしていても、再度実行してもやはり失敗します。

次に、ブラウザ側のキャッシュは確認しましたか?
ただ、リクエストするたびに、サーバ側でエラー文が出るのであれば、このキャッシュのせいである可能性は低いです。

投稿2018/06/11 23:11

mkgrei

総合スコア8560

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/06/12 04:59

I/O処理を連続(1000回ぐらいです)させた際に定期的に発生しています。 I/O処理の記述自体には問題がない(リファレンスのペーストです)と思われます。 ブラウザのキャッシュ確認いたしましたが、問題ないようなので、おそらくサーバー側でのエラーによるものだと思われます。 ご回答ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問