読者です 読者をやめる 読者になる 読者になる

latest log

酩酊状態で書いたエンジニアポエムです。酩酊状態で読んでください。

今時のブラウザが例外発生時にどんな情報を出しているのか調べてみたよ

本文には反映していませんが IE10で Error#stack が実装されました http://blogs.msdn.com/b/ie_ja/archive/2012/05/17/diagnosing-javascript-errors-with-error-stack.aspx

JavaScript では例外が発生すると例外オブジェクトが生成されます。
この例外オブジェクトの仕様は標準化されておらず、各ブラウザで実装が異なります。

最新のブラウザで JavaScript の Error オブジェクトや Error から派生しているオブジェクトが持つ属性を調べてみました。

Safari Stable (Safari 5.1.1)

try {
  throw new Error("hoge");
} catch (err) {
  var i, ary = [];
  for (i in err) { ary.push(i); }
  alert(ary + ""); // -> "line, sourceId, sourceURL"
}
/*
  err.line;      // Number: 2, line number
  err.sourceId;  // Number: 2114265928, unique number
  err.sourceURL; // String: "http://example.com/index.html", URL
  err.message;   // String: "hoge", message
  err + "";      // String: "Error: hoge"
  err instanceof Error; // Boolean: true
 */

Chrome Stable (Chrome 15)

try {
  throw new Error("hoge");
} catch (err) {
  var i, ary = [];
  for (i in err) { ary.push(i); }
  alert(ary + ""); // -> ""
}
/*
  err.message;   // String: "hoge", message
  err + "";      // String: "Error: hoge"
  err instanceof Error; // Boolean: true
  err.stack      // String: "Error: hoge<改行>at http://example.com/index.htm:2:9"
 */

Firefox Stable (Firefox 8)

try {
  throw new Error("hoge");
} catch (err) {
  var i, ary = [];
  for (i in err) { ary.push(i); }
  alert(ary + ""); // -> "fileName, lineNumber"
}
/*
  err.message;   // String: "hoge", message
  err.fileName;  // String: "http://example.com/index.htm"
  err.lineNumber; // Number: 2
  err + "";      // String: "Error: hoge"
  err instanceof Error; // Boolean: true
  err.stack      // String: "@http://example.com/index.htm:2"
 */

Opera Stable (Opera 11.52)

try {
  throw new Error("hoge");
} catch (err) {
  var i, ary = [];
  for (i in err) { ary.push(i); }
  alert(ary + ""); // -> ""
}
/*
  err.message;   // String: "hoge", message
  err + "";      // String: "Error: hoge"
  err instanceof Error; // Boolean: true
  err.stack      // String: "@http://example.com/index.htm:2"
 */

IE Stable (IE 9)

try {
  throw new Error("hoge");
} catch (err) {
  var i, ary = [];
  for (i in err) { ary.push(i); }
  alert(ary + ""); // -> "description, message, name"
}
/*
  err.description; // String: "hoge"
  err.message;   // String: "hoge", message
  err.name;      // String: "Error"
  err + "";      // String: "Error: hoge"
  err instanceof Error; // Boolean: true
 */

まとめ

Chrome, Firefox, Opera は例外発生時のスタック情報を err.stack から取得可能です。

モダンブラウザでは、

try {
  throw new Error(...);
} catch (err) {
  console.log("line = " + (err.line || err.lineNumber || 0));
  console.log("file = " + (err.sourceURL || err.fileName) || "");
  console.log("stack = " + err.stack || "");
}

しておくと、幸せになれるようです。

おまけ

throw new Error("hoge") とせず、throw "hoge" とすると、IE8 以下では意図した動作をしません(バグになります)。
面倒でも throw new Error() と書いてください。

理由は http://d.hatena.ne.jp/uupaa/20100127 を参照してください。

Titanium, ngCore, node.js といった、JavaScript 実行環境においても、ブラウザと同じ JavaScript エンジンを搭載しているものであれば、同様の情報が取得可能です。トライしてみてください。