[JavaScript] 例外発生時にJavaみたいにスタックトレースを出力してデバッグしやすくする方法
こんにちは、最近JavaScriptで大規模開発中の@yoheiMuneです。
JSの大規模開発では、複数人で開発して、クラス数やJSファイル数もたくさんになりやすいです。
そんな時にエラーが発生するとデバッグも大変。
今日は、JavaScriptでJavaのようなスタックトレースを出してデバッグが楽にならないものかと思い調べて、実装してみた結果をブログに書きたいと思います。
スタックトレースとは、スタック(関数の呼び出しをするたびにたまるもの)の一覧を出力する機能です。
関数A→関数B→関数Cとコールしていて関数Cでエラーが発生した場合、そのエラー箇所にたどり着く迄に、 どんなコードを通ってきたかを把握できる機能です。
例えばChromeのデバッグコンソールでは、JavaScriptのエラーが発生すると以下のようなスタックトレースを見ることが出来ます。
Chromeでデバッグしてる時は良いのですが、 実機で動作確認する際などはスタックトレースなどのデバッグ情報が出てこなくデバッグしづらいと感じる事もあります。
今回は、スマホ実機テスト中でもスタックトレースを出してみようと考えた次第です。
なお最近では、iOS6からサポートされているSafariのWebインスペクタ(詳細はこちら)や、 Adobe Shadow(詳細はこちら)でデバッグしやくなりましたが、スタックトレースは出力されません。
(Safari, Chrome, Firefox, iPhone5, Android2.3では動く事を確認しました)
便利ー。
例えば、以下のような関数の呼び出しがある場合には、
上記のようなスタックトレースを見る事で、他人が作った共通クラスがどのように振る舞っているのかを知ることができたり、 ブレークポイントを併用することで各関数内でどのような変数に何の値が入っているのかを知ることができ、 デバッグしやすくなると感じています。
スタックトレースがあるとJava開発者としては少し安心する気がしますw。
デバッグしやすい環境を求めて、これからも色々と探して、ブログにもアウトプットしていきたいと思います。
最後までご覧頂きましてありがとうございました。
JSの大規模開発では、複数人で開発して、クラス数やJSファイル数もたくさんになりやすいです。
そんな時にエラーが発生するとデバッグも大変。
今日は、JavaScriptでJavaのようなスタックトレースを出してデバッグが楽にならないものかと思い調べて、実装してみた結果をブログに書きたいと思います。
スタックトレースとは
サーバーサイドの開発では、例外発生時などによく見るスタックトレースですが、JavaScriptでは一部のブラウザ(Chrome)の開発コンソールくらいでしか見ることが出来ません。スタックトレースとは、スタック(関数の呼び出しをするたびにたまるもの)の一覧を出力する機能です。
関数A→関数B→関数Cとコールしていて関数Cでエラーが発生した場合、そのエラー箇所にたどり着く迄に、 どんなコードを通ってきたかを把握できる機能です。
例えばChromeのデバッグコンソールでは、JavaScriptのエラーが発生すると以下のようなスタックトレースを見ることが出来ます。
Uncaught Error: original Error stacktrace.html:31 1. f1 stacktrace.html:31 2. f2 stacktrace.html:32 3. f3 stacktrace.html:33 4. (anonymous function)(コンソールに出力されたErrorの横にある下矢印をポチッと押すと見ることが出来ます)
Chromeでデバッグしてる時は良いのですが、 実機で動作確認する際などはスタックトレースなどのデバッグ情報が出てこなくデバッグしづらいと感じる事もあります。
今回は、スマホ実機テスト中でもスタックトレースを出してみようと考えた次第です。
なお最近では、iOS6からサポートされているSafariのWebインスペクタ(詳細はこちら)や、 Adobe Shadow(詳細はこちら)でデバッグしやくなりましたが、スタックトレースは出力されません。
JavaScriptの例外発生時にスタックトレースを出力する
JavaScriptのスタックトレースは、以下のように例外オブジェクトからスタックトレースを取得することが出来ます。(Safari, Chrome, Firefox, iPhone5, Android2.3では動く事を確認しました)
// 例外オブジェクトからスタックトレースを出力する関数。 function printStackTrace(e) { if (e.stack) { // 出力方法は、使いやすいように修正する。 console.log(e.stack); alert(e.stack); } else { // stackがない場合には、そのままエラー情報を出す。 console.log(e.message, e); } } try { // 例外を発生させてみる。 throw new Error("original Error"); } catch (e) { printStackTrace(e); }例外オブジェクト(e)はstackというものを持っていて、それがスタックトレースとして出力できます。
便利ー。
例えば、以下のような関数の呼び出しがある場合には、
function f1() {throw new Error("original Error");} function f2() {f1();} function f3() {f2();} try { f3(); } catch (e) { printStackTrace(e); }以下のようなスタックトレースが出力されます(使うブラウザにより少し形式は異なります)。
Error: original Error at f1 (http://localhost/labo/work/stacktrace.html:33:9) at f2 (http://localhost/labo/work/stacktrace.html:36:16) at f3 (http://localhost/labo/work/stacktrace.html:37:16) at http://localhost/labo/work/stacktrace.html:40:3
上記のようなスタックトレースを見る事で、他人が作った共通クラスがどのように振る舞っているのかを知ることができたり、 ブレークポイントを併用することで各関数内でどのような変数に何の値が入っているのかを知ることができ、 デバッグしやすくなると感じています。
最後に
e.stackが対応していないブラウザもあるようですが、最近よく使うスマホでは一応対応しているようです。スタックトレースがあるとJava開発者としては少し安心する気がしますw。
デバッグしやすい環境を求めて、これからも色々と探して、ブログにもアウトプットしていきたいと思います。
最後までご覧頂きましてありがとうございました。