Perhaps the simplest form of debugging is adding a
trace() statement to your code to print out when a function is entered or the value of a variable at a particular point.
In addition to the global
trace() method, the
<mx:TraceTarget/> tag allows you to see communication with a remote server. This can be particularly useful in determining what (if anything) your server is returning for your requests.
TraceTarget actually sets up the Flex logging API. The appearance of the server communication is down to the fact that the internal Flex components
mx.data.* all use this API. We’ll come back to logging later.
A more interactive strategy for finding errors is to use a debugger. If you’re fortunate enough to have access to Flex Builder, you have a built-in graphical debugger that will allow you to set breakpoints, inspect variables etc. If not, the Flex SDK comes with a command line debugger – fdb. This can be found in the bin directory and started by typing
fdb and then
run location of swf or just
fdb location of swf directly. You can use
tutorial at the fdb prompt to get information on the commands available. Basically you can set breakpoints (even conditional ones which the Flex Builder version doesn’t support), step through code and print or change the values of variables. It’s not quite as easy to use as the Flex Builder version but it will get the job done. There are also some 3rd party free tools available such as Demonster Debugger which can give you some of the features of a graphical debugger along with memory usage and frame rates but unfortunately, don’t support breakpoints.
Here’s Adobe’s info on the command line debugger and here’s a great chapter from the book Programming Flex 3 that OReilly have kindly put on their website that covers the command line debugger, the Flex Builder debugger and the logging framework.
The aforementioned OReilly chapter covers this topic really well. You can define different levels of logging (debug, warn etc) and filter on which you want to be logged. You can also determine what happens to your log data so for instance, you could arrange to log particularly worrying errors back to your server or perhaps to a local file that support staff could request users email them if problems occur.
Like most modern languages, ActionScript3 has the concept of exceptions and the associated
Runtime exceptions occur during the operation of the application, often due to unexpected input or problems communicating with remote systems. In these situations, you can place the potentially troublesome code within a try-catch block like so:
some dangerous code
do something about the error
catch block, you can access properties and methods of the
getStackTrace() – for debugger versions of the Flash player, returns the call stack for the error as a
toString() which returns “
Error” by default or the value contained in
message if defined.
There are a number of error classes defined both by ECMAScript and ActionScript, more details on which can be found here.
You may define multiple
catch blocks to deal with specific error classes. The rules are that the first catch block to satisfy the error will be executed and only one
catch block may be run. For this reason, you should never use the base class
Error before other catch blocks as it will always take the error.
throw statement allows you to raise an exception which will bypass the normal operation of your application. You would normally do this if you have discovered a condition that prevents the normal flow of execution. You may either throw an existing error type or create your own by extending the
finally statement should be placed after all
catch blocks and is used to define code that should be executed regardless of whether an exception was raised or not (generally this is used for something like freeing resources requested in the
Flash player 10.1 introduces the concept of a global error handler so you can trap errors that have otherwise not been processed. This allows you to have a catch-all point where you can at least log something and potentially inform the user before gracefully exiting.
According to the release notes (pdf), the current beta 2 of 10.1 has this functionality disabled but here’s a blog post from Christian Cantrell on how to do it using Air and here’s some more detail about the