Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to find the function and/or line number that caused an error in ActionScript 3.0 without using debug mode?

I'm currently trying to implement an automated bug reporter for a Flex application, and would like to return error messages to a server along with the function/line number that caused the error. Essentially, I'm trying to get the getStackTrace() information without going into debug mode, because most users of the app aren't likely to have the debug version of flash player.

My current method is using the UncaughtErrorEvent handler to catch errors that occur within the app, but the error message only returns the type of error that has occurred, and not the location (which means it's useless). I have tried implementing getStackTrace() myself using a function name-grabber such as

            private function getFunctionName (callee:Function, parent:Object):String {
                for each ( var m:XML in describeType(parent)..method) {
                    if ( this[m.@name] == callee) return m.@name;
                }
                return "private function!";
            }

but that will only work because of arguments.callee, and so won't go through multiple levels of function calls (it would never get above my error event listener).

So! Anyone have any ideas on how to get informative error messages through the global error event handler?

EDIT: There seems to be some misunderstanding. I'm explicitly avoiding getStackTrace() because it returns 'null' when not in debug mode. Any solution that uses this function is what I'm specifically trying to avoid.

like image 865
Edward H Avatar asked Jun 28 '11 19:06

Edward H


2 Answers

Just noticed the part about "I don't want to use debug." Well, that's not an option, as the non-debug version of Flash does not have any concept of a stack trace at all. Sucks, don't it?


Not relevant but still cool.

The rest is just for with the debug player.

This is part of my personal debug class (strangely enough, it is added to every single project I work on). It returns a String which represents the index in the stack passed -- class and method name. Once you have those, line number is trivial.

    /**
 * Returns the function name of whatever called this function (and whatever called that)...
 */
public static function getCaller( index:int = 0 ):String
{
    try
    {
            throw new Error('pass');
    } 
    catch (e:Error)
    {
        var arr:Array = String(e.getStackTrace()).split("\t");
        var value:String = arr[3 + index];
        // This pattern matches a standard function.
        var re:RegExp    = /^at (.*?)\/(.*?)\(\)/ ;     
        var owner:Array  = re.exec(value);
        try 
        {
            var cref:Array = owner[1].split('::');
            return cref[ 1 ] + "." + owner[2];
        }
        catch( e:Error )
        {
            try
            {
                re = /^at (.*?)\(\)/; // constructor.
                owner = re.exec(value);
                var tmp:Array    = owner[1].split('::');
                var cName:String = tmp.join('.');
                return cName;
            }
            catch( error:Error )
            {
            }
        }
    }
    return "No caller could be found.";
}

As a side note: this is not set up properly to handle an event model -- sometimes events present themselves as either not having callers or as some very weird alternate syntax.

like image 177
cwallenpoole Avatar answered Nov 02 '22 21:11

cwallenpoole


You don't have to throw an error to get the stack trace.

var myError:Error = new Error();
var theStack:String = myError.getStackTrace();

good reference on the Error class


[EDIT]
Nope after reading my own reference getStackTrace() is only available in debug versions of the flash player.
So it looks like you are stuck with what you are doing now.

like image 2
The_asMan Avatar answered Nov 02 '22 20:11

The_asMan