Node.jsでカレント実行行を取得する
Node.jsでエラー発生時に適当に console.log とかを埋めて、しかもそれが複数箇所になってくると、エラーメッセージは分かるがそれがどこで発生したエラーなのかが分からなくて困ったりする。キャッチしたエラーオブジェクトが普通にthrowされたErrorオブジェクトならerr.stackでコールスタックが取得できるからまだしも、只の文字列や独自Errorをcallback(new Error("オレオレメッセージ"))とかで渡されるとコールスタックが取れないのでどうしようとした足跡。
試行錯誤
で、以下の様な関数を作ってみた。仕組みは簡単で、throwしないと行番号取得できないならダミーで例外発生させちゃえば良いじゃないって感じ。*1
function getCallStack() { try { throw new Error("DUMMY"); } catch(e) { return e.stack.split(/[\r\n]+/).filter(function(v,v2,v3){ return /^ at .*:[0-9]+:[0-9]+/.test(v); }); } }
試しに適当な箇所で console.log(getCallStack()) すると以下の様にコールスタック情報を配列で取得できるようになる。
[ ' at getCallStack (/home/kawaz/workspace/test/app.js:866:11)', ' at /home/kawaz/workspace/test/app.js:853:19', ' at Object.(/home/kawaz/workspace/test/app.js:440:15)', ' at param (/home/kawaz/.nvm/v0.4.6/lib/node/.npm/connect/1.3.0/package/lib/middleware/router.js:148:21)', ' at param (/home/kawaz/.nvm/v0.4.6/lib/node/.npm/connect/1.3.0/package/lib/middleware/router.js:159:15)', ' at pass (/home/kawaz/.nvm/v0.4.6/lib/node/.npm/connect/1.3.0/package/lib/middleware/router.js:164:10)', ' at /home/kawaz/.nvm/v0.4.6/lib/node/.npm/connect/1.3.0/package/lib/middleware/router.js:154:19', ' at /home/kawaz/workspace/test/app.js:571:9', ' at [object Object]. (/home/kawaz/.nvm/v0.4.6/lib/node/.npm/mongodb/0.9.2/package/lib/mongodb/collection.js:448:35)', ' at [object Object].emit (events.js:67:17)' ]
なので、今まで console.log(err) とかしてた代わりに、console.log(err, getCallStack()[1]) としておけばconsole.log()を実行した行番号付きで以下のように出力されるようになる。
オレオレメッセージ at /home/kawaz/workspace/test/app.js:853:19
ちゃんとしたアプリにしようと思ったら微妙かもだけど、ちゃちゃっとコード書くときには便利なTipsだと思います。
追記) 文字列処理なしで取れました!
結論、Error.prepareStackTraceを使えば解決する。
あと関係ないけど、はてなのツイッター記法を初めて知った。一連のツイートを貼り付ける時とかに便利だなコレ。
*1:この関数ではとりあえず文字列の配列を返すけど、行番号と列番号は簡単にパースできるので省略。