普通に throw new Error("msg") だと出力が寂しい。。。
デバッグのとき切ない。。。
// foo.js load("bar.js"); function foo_func(){ println("foo_func"); bar_func(); } try{ foo_func(); }catch(ex){ println("* something wrong *"); println(ex); for(var k in ex){ println(k + " (" + ex[k] + ")"); } }
// bar.js function bar_func(){ println("bar_func"); throw new Error("{msg}"); }
結果:
$ jrunscript foo.js foo_func bar_func * something wrong * Error: {msg} message ({msg}) name (Error) fileName () lineNumber (0)
ので、stack trace(Java) とか call stack とか back trace(Ruby)とか呼ばれるものが出るようにしてみた。
// foo.js function getCallStack(){ var stack = []; try{ eval("."); }catch(e){ var lines = e.stack.split("\n"); for(var i=lines.length; i>=1; i--){ var line = lines[i]; if(typeof line === "undefined" || line.match(/^\s*$/)) { // skip }else{ stack.push(line.replace(/^\s*/, "")); } } } return stack; } function dumpError(ex){ var s = ""; s += ex.name + ": "; s += ex.message + "\n"; if(typeof ex.stack === "undefined"){ s += "(no stack)"; }else if(typeof ex.stack === "object" && ex.stack.length){ for(var i=ex.stack.length-1; i>=0; i--){ s += ex.stack[i] + "\n"; } }else{ s += ex.stack; } println(s); } function MyError(msg){ this.name = "MyError"; this.message = msg; var stack = getCallStack(); this.stack = []; for(var i=0; i<stack.length-1; i++){ this.stack.push(stack[i]); } } //////////////////////////////// function foo_func(){ println("foo_func"); bar_func(); } try{ load("bar.js"); foo_func(); }catch(ex){ println("* something wrong *"); dumpError(ex); }
// bar.js function bar_func(){ println("bar_func"); throw new MyError("{msg}"); }
結果:
$ jrunscript foo.js foo_func bar_func * something wrong * MyError: {msg} at bar.js:5 (bar_func) at foo.js:55 (foo_func) at foo.js:60
それっぽい感じになったけど小手先感ある。
もっとちゃんとしたやり方がありそう。