Strategies for debugging

Overview

Debugging JSFL can be a lonely and frustrating task at the best of times. If you're not struggling to find out which properties you can successfully access on the object type you're currently referencing (Shape, Element, Instance, SymbolInstance?), perhaps you're just coming up against some inexplicable JavaScript error.

JavaScript errors happen for a variety of reasons:

  • Syntax errors, such as a missing comma or quote
  • Runtime errors, such as a trying to access a non-existent object property
  • Environmental errors, such as a document not being open
  • Indirect errors, such as a bug in a loaded file

To add to this, Flash's error messages can be misleading, incorrect, or even missing!

Deciphering misleading error messages

The following is a brief summary of some of the misleading or confusing errors you may encounter in flash, and reasons for why they may happen:

"The following JavaScript error(s) occurred:" (but no further details)

Flash CS4

  • A runtime or syntax error in a file being run by fl.runScript() or xjsfl.file.load();
  • A runtime or syntax error in code which is currently running inside a XUL dialog
  • Attempting to access unset colorMode properties like brightnes or, tintcolor, or IDE-only properties like morphshape and shapehints
  • Accessing a file URI longer than 260 chars (note that escaped spaces add 3, not 1, characters: %20)
  • You passed a path containing Windows back-slashes to FLfile

Flash CS5 / CS5.5

  • Could be anything. CS5 seems to mask a lot of errors that would have shown up in CS4. Very unhelpful.
  • Calling document.getTimeline() when the Font Mapping dialog is being shown on file open
"The following JavaScript error(s) occurred: Open a Flash document (FLA) before running this script"
  • You are attempting to load a file with runtime or syntax errors in whilst there is no document open. This also occurs if you add erroneous files to the xJSFL bootstrap. Re-loading the file when there is a document open will result in a silent error as described above
"TypeError: foo has no properties"
  • You are attempting to set a property on a variable whose value is null or undefined. This can often occur when building more complicated scripts, and you have lots of object dependencies

Tips for debugging

Use the Output class to inspect objects

The output class is your best friend. It has a variety of powerful methods to put on display the very guts of the element, item, object or value you're currently working with. Often seeing the object broken down in front of you can give you the vital clue you need to make a breakthrough.

For more details see the Output class.

Use xjsfl.debug.error() to print the error stack

When you come up against runtime errors in your JSFL code, the best way to get to the bottom of them is to use these two functions. xJSFL will printout the complete error stack, including filename and line numbers so you can get to the root of the problem.

For more information, see the section on Handling errors.

Use xjsfl.debug.file() or set xjsfl.debug.state to true

One of the most annoying things in JSFL development is running files which seem to fail silently. The cause of this is always errors within the loaded file, which fl.runScript() won't alert you to.

To work round this limitation, test your files using xjsfl.debug.file()  or set xjsfl.debug.state to true, which overrides the native fl.runScript() with a wrapper function that instead reads and eval()s the contents of any future loaded files (rather than running them) causing any errors to be printed to the output panel:

xjsfl.debug.state = true;
xjsfl.debug.file(uri);

Note that because the loaded files are not physically run, it will cause the URI-specific function scriptDir and fl.scriptURI to fail.

Test individual scripts in isolation

If a script has dependencies on other scripts, and you're getting the mysterious silent JavaScript error, then attempt to define the problem script, then run it in isolation, in a try/catch/debug() as outlined earlier, if you can. Once a script is no longer running via fl.runScript(), errors should be output to the Output panel.

Test individual functions in isolation using xjsfl.debug.func()

If you suspect that the problem may be  a single function, you can test it using xjsfl.debug.func(). This calls the function, first wrapping in a try/catch, sending any caught errors to xjsfl.debug.error().

Add traces to your code

The final tool in your debugging arsenal is of course, the humble trace(). The only advice I have for adding traces, is to make sure you include an identifiable "string" segment within the trace you can later search for to remove the trace, such as:

trace("element.value is: " + value); // easy to locate later
trace(value); // hard to locate later

Debugging panels and complex scripts

Errors in Flash panels

Flash won't alert you to AS3 runtime errors in Flash panels, and this can be particularly frustrating as things will just look like they fail for no reason. Worse, you have no idea if the problem is caused by AS3 or JSFL code - either directly, or indirectly. Add traces in your AS3 code using JSFL.trace() and JSFL.inspect() to dump to the output panel data that you can check. Remember, the vanilla AS3 trace() won't do anything inside a panel.

Panel actions that were working, suddenly aren't

As xJSFL allows your scripts to get evermore complex, relying on multiple libraries and classes, you can sometimes find that things just stop working, usually because a fix or bit of code you wrote in one class, affects another class in a way that you might not have imagined.

More often than not there will be errors that are printed to the Output panel, but they may be lost amongst other trace messages, or you may have inadvertently called a clear() before having seen the xJSFL or JSFL error message.

Last word

If you've come across any other errors yourself, please do comment, and I'll add them to this page.

Next steps

2 Responses to Strategies for debugging

  1. Curtis Mechling says:

    You mentioned on ‘https://xjsfl.vercel.app/support/guides/debugging/strategies-for-debugging’ that ‘Remember, the vanilla AS3 trace() won’t do anything inside a panel.’. This is not entirely true, at least not on CS5.5. You just have to enable ‘Permit debugging’ in the publish settings of the panel fla file.

  2. Dave Stewart says:

    Thanks Curtis – nice tip!

    I use that in FlashDevelop, but didn’t realise you could get the same result in Flash CS. I’ll update the page to reflect that.