日頃の行い

個人的な日頃の行いをつらつら書いてます\\\\ ٩( 'ω' )و ////

node.jsのライブラリzombie.jsでステータス 400 以上は標準エラー出力が出てしまう

node.jsを使う機会があって、zombie.jsで、あるページにアクセスした時、404のページに飛ぶはずってテストを書く予定だった。

すごく使いやすいからみんな使うといいと思う(すてま
インストールも簡単。

zombie.jsが実行ファイルだとして、
/path/to/zombie.js
/path/to/node_modules/{いろんなライブラリ}
みたいな設定。
インストールするライブラリはzombieのみ(ほんとはvowsとか使ったけどw)

なので、nodeをインストールした時に自動的にインストールされるnpmコマンドでインストールすればよくて、

npm install zombie

でカレントディレクトリのnode_modulesディレクトリ以下にzombieがインストールされる。
オプションとして-gをつければnodeのグローバルなライブラリとしてインストールが出来る。

この状態で、

var Zombie  = require("zombie"),
    browser = new Zombie(),
    url     = "http://huwshimi.com/404";


browser.visit(url)
        .then(function(){
            console.log(browser.text("title"));
        })
        .fail(function(err){
            console.dir(err);
        });

と書いて、

node zombie.js

と実行する。そうすると、色々出てくるんだけど、

Server returned status code 404 from http://huwshimi.com/404 Error: Server returned status code 404 from http://huwshimi.com/404
    at /path/to/node_workspace/zombie_404/node_modules/zombie/lib/zombie/window.js:411:23
    at /path/to/node_workspace/zombie_404/node_modules/zombie/lib/zombie/eventloop.js:234:18
    at Object._onImmediate (/path/to/node_workspace/zombie_404/node_modules/zombie/lib/zombie/eventloop.js:139:11)
    at processImmediate [as _immediateCallback] (timers.js:330:15)
[Error: Server returned status code 404 from http://huwshimi.com/404]

これは・・・ぺろ・・・青酸k・・・いや、標準エラー出力

ちなみに利用したURL
http://gigazine.net/news/20110629_30_creative_404/
で紹介されてた404のページw

この標準エラー出力は、困ったことにオプションとかで消すことが出来ず、ソースを見る限り、ステータスコードが400以上の時に必ずエラーが発生する。
そして、catchもできない。
browser.on("error",fn())
とかでなんとかできるかとか思ったけど無理だった。

色んな所見たんだけど解決策なかった。
こことか
あともう一個Issueのページが有ったんだけど見失った。。。

なので、とりあえず、protptypeで拡張してなんとかすることにした。

結果

var Zombie  = require("zombie"),
    browser = new Zombie(),
    url     = "http://huwshimi.com/404",
    temp_emit = browser.emit;

Zombie.prototype.ERROR_404_MESSAGE_NO_URL = "Error: Server returned status code 404 from ";

Zombie.prototype.is_404_error = function(event,error_message){
    return (event === 'error' && error_message.toString() === this.ERROR_404_MESSAGE_NO_URL + this.url);
}

Zombie.prototype.emit = function(event,argv){
    if(this.is_404_error(event,argv)){
        return true;
    }
    return temp_emit(event,argv);
}

browser.visit(url)
        .then(function(){
            console.log(browser.text("title"));
        })
        .fail(function(err){
            console.dir(err);
        });

これで一応標準エラー出力はでなくなった。

ちなみに、emitはEventEmitterのメソッドで、(参考)たぶん、Browserオブジェクトにprototypeで継承するような形で利用している。(たぶん,ソース見たけどあんまりわからなかった←)