Thursday, June 19, 2008

JavaScript Stacktrace

Just the other day, I was debugging an error in application which works only in Internet Explorer. The application is pretty complicated, so I really missed my favourite Firebug.

I was looking for some way to investigate the stack trace and I came upon the reserved word arguments in the JavaScript language.

Basically it allows you to access the arguments of the function as an array. It has couple of special properties, which come in very handy.

  • arguments.callee - references the function itself (as function object).
  • arguments.callee.caller - references the function that called me
  • arguments.callee.name - Mozilla only extension, which returns the name of the function

As you can see, in IE we can't access the name of the function object as a property. However we can access the whole function body as a text string. So we just use a regular expression to cut out, the first word that follows the function. It's an ugly hack, so that it works in IE, but it works reasonably good.

function stacktrace()
{
 re = /function\W+([\w-]+)/i;

 var f = arguments.callee;
 var s = "";
 while (f)
 {
  s += (re.exec(f))[1] + '('; 

  for (i = 0; i < f.arguments.length - 1; i++)
  {
   s += "'" + f.arguments[i] + "', ";
  }

  if (arguments.length > 0)
  {
   s += "'" + f.arguments[i] + "'";
  }

  s += ")\n\n";

  f = f.arguments.callee.caller;
 }
 alert(s);
}

It would be much more elegant, if split into two functions, where one would be providing the name of the function from the string, but for copy pasting purposes, it's much easier to have one function in total.

To try it out, just click here - some_function('first', 'second', true);

You should get result, that looks like this:

2 comments:

Gagan said...

Nice

Miron Brezuleanu said...

Hello, great post.

One small thing:

line 16 should read
if (f.arguments.length > 0)

(you left out the "f." which causes arguments list to be lost).