Home > Ajax > dcomments.blogs.a.ajaxian  [ Add to favorite]  Print Message

Getting a JavaScript stracktrace in any browser


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