mongooseのconnectの接続エラー(node.js)のハンドリング

mongooseのconnect実行時、mongodが上がっていなくてもthrowされないので、そのあたりのハンドリングがしたくてmongooseのソースを呼んでみました。(非同期IOだから当たり前ですが・・)
たぶん、コールバックを指定すれば良いとかそのくらいの事なんだろうなーと思いつつも、せっかくなのでちゃんとソースを呼んでみる。

mongooseのconnect

connectが定義されているのは、
mongoソースの「index.js」です。
(場所:自分はnpmインストールなので/usr/local/lib/node/.npm/mongoose/1.3.7/package/lib/mongoose)

まずはcocnnect定義の大元から。

index.js

103〜106行目

Mongoose.prototype.connect = function (){ 
  this.connection.open.apply(this.connection, arguments);
  return this;
};

this.conncection.openを呼ぶ。
(なぜthis.connectionのopenを呼んでいるのに、applyでまたthis.connectionを指定しているかは謎。。)

this.connectionって何がはいっているんだろう?
このindex.js上ではthis.connectionに代入してる様子がなさそうだが、
24〜31行目

function Mongoose () {
 〜省略〜
  this.createConnection(); // default connection
};

このcreateConnectionが怪しいので追ってみる。


73〜79行目

Mongoose.prototype.createConnection = function () {
  var conn = new Connection(this);
  this.connections.push(conn);
  if (arguments.length)
    conn.open.apply(conn, arguments);
  return conn;};
  • Connectionオブジェクトを作成
  • collectionsに追加
  • 作成されたConnectionオブジェクトを
  • return Connectionオブジェクト

Connectionオブジェクトってなんだ?
252行目

var Connection = require(driver + '/connection');

あった。driverの下のconnectionがつっこまれるらしい。driverには何が入っているのだろう。
244行目

var driver = global.MONGOOSE_DRIVER_PATH || './drivers/node-mongodb-native';

ここで入れてるようだ。自分の環境ではデフォの値(node-mongodb-native)だ。
(他のdrriverも無い)
なので、./drivers/node-mongodb-native/connection.jsがrequireされる。


だんだん近づいてきた気がする。
あとは、openの定義があれば良いのだが。

./drivers/node-mongodb-native/connection.js

このソースの結末的には85行目で、

module.exports = NativeConnection;

NativeConnectionをつっこんでいるらしい。じゃあNativeConnectionにopenがある?
17〜25行目

function NativeConnection() {
  Connection.apply(this, arguments);
};
/**
 * Inherits from Connection.
 */
NativeConnection.prototype.__proto__ = Connection.prototype;

openの定義はこのソースに無い。ただ、この「NativeConnection」には「Connection」をprototypeでつっこんでいるのでここでopenを定義していそう。
6行目

var Connection = require('../../connection')
./connection.js

またファイル名が同じで「connection.js」だが、これはmongooseディレクトリ(/usr/local/lib/node/.npm/mongoose/1.3.7/package/lib/mongoose)の直下。

やっとopen発見。
70行目

Connection.prototype.open = function (host, database, port, callback) {

で、その核の部分
122〜132行目

  // open connection
  this.doOpen(function (err) {
    if (err) {
      if (typeof callback == 'function')
        callback(err);
    } else {
      self.onOpen();
      if (typeof callback == 'function')
        callback(null);
    }   
  }); 

あー、やっぱりcallbackにfunctionを渡せば良いんですね。
わかってたけど、わざわざ追ってみました。

なので、mongooseのconnectoで接続のエラー確認は

var mongoose   = require('mongoose'),
mongoose.connect('mongodb://localhost/mydb',
  function (err){
    if(err){
    console.log(err);
  }else{
    console.log('connection success!');
  }
}
);

ということでコールバックでエラーを確認するということでした。
無駄にソースが追ってみたくなることってありますよね。