6

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.

Jacob Eggers
  • 9,062
  • 2
  • 25
  • 43
Edward H
  • 98
  • 7
  • 1
    I think this is a really important question. Sometimes testing in a debug version of the player isn't always possible, you might be deploying to a client machine who has a different setup without debug player. And it's not as simple as 'it works on yours, it works on theirs', as there are sometimes other factors, network access, etc. Very interested what answers get posted here – Chris Jun 28 '11 at 20:46
  • Funny, we've had a lot of similar questions in the past, one of the most recent: http://stackoverflow.com/questions/6505200/release-with-debug-in-flex-air/6508981 What needs to be remembered here is that the release version has no metadata associated with it. The only way to know which function failed would be to have unique errors that can be caught and then you just need to search your project for that error string. – J_A_X Jun 28 '11 at 21:24
  • @Chris : Indeed, one of the more interesting examples I've been witness to was the necessity to get a stack trace from a swf compiled to target the Release player that lives inside an mProjector .exe. While I was able to package a debug version of the player that didn't help because the error *only* happened in the release version! No way to get a stack trace from that environment! My only recourse was to just log every function call and barf it out if an error occurred during the main game loop. – scriptocalypse Jun 28 '11 at 23:10

2 Answers2

3

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.

cwallenpoole
  • 79,954
  • 26
  • 128
  • 166
2

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.

The_asMan
  • 6,364
  • 4
  • 23
  • 34
  • This method requires using 'getStackTrace()', which will return 'null' when not in debug mode. My post explicitly asks for NOT this solution. – Edward H Jun 28 '11 at 20:29
  • Yeah I just found that out after looking over my reference lol – The_asMan Jun 28 '11 at 20:35
  • I'm curious though why would you want to do this anyway. Can you give an example or something. I never publish faulty code :) I mean if it does happen I hear about it right away and the fixes are made. – The_asMan Jun 28 '11 at 20:40
  • The best Idea I can come up for you is to create a custom error class and throw errors using that then catch it with a try catch and send that off to your server. – The_asMan Jun 28 '11 at 20:45
  • I was going to try and send automated error reports to a errorlog server so I can see what's breaking down. I know that AS3 tends to work well despite random errors, but I still would like to know about the tiny things I can fix. If I could grab a stack dump of any errors that occur, it'd help with code fixing. And like all large (highly interactive) projects, this app isn't completely bug free, and not easily testable. – Edward H Jun 28 '11 at 20:45
  • Another thing you might add to what you have is the class name – The_asMan Jun 28 '11 at 21:44
  • This is actually now available in 11.5, see http://stackoverflow.com/questions/149073/stacktrace-in-flash-actionscript-3-0 – SleepyCal May 07 '14 at 15:30