Monday, August 18th, 2008

Getting a JavaScript stracktrace in any browser

Category: JavaScript, Tip

<>p>Eric Wendelin has posted on getting a JavaScript stack trace no matter that the browser.

With Firebug you can call console.trace() but what about the rest?

Luke Smith took Eric’s work and added to it, ending up with:

javascript
< view plain text >
  1. (function () {
  2. YOUR_NAMESPACE.getStackTrace = (function () {
  3.  
  4. var mode;
  5. try {(0)()} catch (e) {
  6.     mode = e.stack ? 'Firefox' : window.opera ? 'Opera' : 'Other';
  7. }
  8.  
  9. switch (mode) {
  10.     case 'Firefox' : return function () {
  11.         try {(0)()} catch (e) {
  12.             return e.stack.replace(/^.*?\n/,'').
  13.                            replace(/(?:\n@:0)?\s+$/m,'').
  14.                            replace(/^\(/gm,'{anonymous}(').
  15.                            split("\n");
  16.         }
  17.     };
  18.  
  19.     case 'Opera' : return function () {
  20.         try {(0)()} catch (e) {
  21.             var lines = e.message.split("\n"),
  22.                 ANON = '{anonymous}',
  23.                 lineRE = /Line\s+(\d+).*?in\s+(http\S+)(?:.*?in\s+function\s+(\S+))?/i,
  24.                 i,j,len;
  25.  
  26.             for (i=4,j=0,len=lines.length; i<len; i+=2) {
  27.                 if (lineRE.test(lines[i])) {
  28.                     lines[j++] = (RegExp.$3 ?
  29.                         RegExp.$3 + '()@' + RegExp.$2 + RegExp.$1 :
  30.                         ANON + RegExp.$2 + ':' + RegExp.$1) +
  31.                         ' -- ' + lines[i+1].replace(/^\s+/,'');
  32.                 }
  33.             }
  34.  
  35.             lines.splice(j,lines.length-j);
  36.             return lines;
  37.         }
  38.     };
  39.  
  40.     default : return function () {
  41.         var curr  = arguments.callee.caller,
  42.             FUNC  = 'function', ANON = "{anonymous}",
  43.             fnRE  = /function\s*([\w\-$]+)?\s*\(/i,
  44.             stack = [],j=0,
  45.             fn,args,i;
  46.  
  47.         while (curr) {
  48.             fn    = fnRE.test(curr.toString()) ? RegExp.$1 || ANON : ANON;
  49.             args  = stack.slice.call(curr.arguments);
  50.             i     = args.length;
  51.  
  52.             while (i--) {
  53.                 switch (typeof args[i]) {
  54.                     case 'string'  : args[i] = '"'+args[i].replace(/"/g,'\\"')+'"'; break;
  55.                     case 'function': args[i] = FUNC; break;
  56.                 }
  57.             }
  58.  
  59.             stack[j++] = fn + '(' + args.join() + ')';
  60.             curr = curr.caller;
  61.         }
  62.         return stack;
  63.     };
  64. }
  65. })();

Related Content:

Posted by Dion Almaer at 5:43 am
1 Comment

++++-
4.1 rating from 22 votes

1 Comment »

Comments feed TrackBack URI

http://pastie.org/254922 <– this example works.

I’ve formatted the code for read-ability.
I haven’t changed any variable names.

Comment by roosteronacid — August 18, 2008

Leave a comment

You must be logged in to post a comment.