Advertisement

Alfred Debugging

by

This Cyber Monday Tuts+ courses will be reduced to just $3 (usually $15). Don't miss out.

No matter how carefully code is written, problems will appear that need to be fixed. The art of removing programming errors is called debugging. Since Alfred runs scripts in a sub-shell process, debugging takes on a new level of trickiness.

In this tutorial I'll show you how to debug your Alfred scripts. If you are new to Alfred, you might want to check out the making of scripts in Alfred for Beginners, Intermediates, and Advanced users. Those tutorials will get you up to speed in creating Alfred Workflows. But since you are human, you are bound to have a few errors in the scripts. It’s time for a bug hunt.

The example script is a broken version of Todo Workflow for using TaskPaper with Alfred. You do not have to have TaskPaper to use this workflow. You can setup any text editor to edit your tasks. All tasks are kept in a plain text file. The broken copy is in the download for this tutorial. Download and install it to follow the tutorial.

Command Line Debugging

When an Alfred script dies, you often do not know about it except for the fact that the effect you wanted did not happen. For a Script Filter, a bug in the script will dump you into the default searches without any explanation.

Default Search from a buggy Script Filter

When you type t:showjournal in the Alfred prompt, this is what you will get. Just looking at this level, it is impossible to know what the problem is. Since scripts are executed in a sub-process shell, you just can not see the results. Therefore, the script must be ran on the command line to see anything.

Opening the Workflow Directory

For proper execution of the script, it needs to be executed in the workflow directory just like it would be done inside of Alfred. Open the Script Filter that needs to be debugged and copy the script. The button under the script labeled Open workflow folder will open a Finder (or Path Finder) window in the directory needed to execute the script.


Opening the Workflow Directory in Finder or Path Finder

This is where the script needs to be executed. This path is difficult to find. An easy way to open a terminal there is to use an Alfred workflow!

TerminalFinder using Finder to Terminal Command

To open the directory in a terminal shell, you can use the Alfred Workflow TerminalFinder to open a Finder or Path Finder directory in a terminal session (or iTerm). Typing ft will open a terminal in the directory from a Finder window.

TerminalFinder using Path Finder to Terminal Command

Typing pt will open a terminal in the directory from a Path Finder window.

Workflow Directory in Terminal

You'll end up with a Terminal window open to the directory. Notice the long path in blue. That would be impossible to remember and navigate there by hand! Use a text editor to create a file at that location called testing.php and paste the script in to it. You have to add <?php on the top most line for the PHP interpreter to properly interpret the script.

You also need to remove the {query} Alfred macro since the PHP interpreter will not know what to do with it. Alfred translates that macro to the string on the Alfred prompt before passing the script to the PHP interpreter.

Once these changes have been made, you can test the script by typing:

php testing.php

That will run the script and the output will be seen in the Terminal window.

Faulty Script Ran on Command Line
Faulty Script Ran on Command Line

Yep, it crashed alright. You will see from the output that a variable is not defined and the time zone for the date function has not been set. That time zone setting kills a large number of PHP scripts in Alfred!

You can easily debug your scripts this way, but it involves a long process that is bound to create more bugs than solve. If you forget to add the PHP preamble or remove the Alfred macro, the debugging will become a harder process. What is needed is a way to get to this information from inside Alfred!

Alfred Debugger

Since version 2.2 of Alfred, Alfred now allows for this type of debugging. In the workflow design area, press the bug graphic at the top right corner of the design area and select the block you want to debug. The debugger opens at the bottom.

Alfred Debugger
Alfred Debugger

You can set the debugger to show just Errors and Warnings, or you can set it to show All information. Setting it to All information will give you the most information.

Error Message in Alfred Debugger
Error Message in Alfred Debugger

When you run the t:showjournal command now, you will see the exact same information that was found on the command line. Much easier! Now for the bug hunt!

[ERROR: alfred.workflow.input.scriptfilter] Code 0: PHP Notice:  Undefined variable: journaldir in Command line code on line 11
ls: /*.txt: No such file or directory
PHP Warning:  date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in Command line code on line 12
[ERROR: alfred.workflow.input.scriptfilter] XML Parse Error 'The operation couldn’t be completed. (NSXMLParserErrorDomain error 4.)'. Row (null), Col (null): 'Document is empty' in XML:
Notice: Undefined variable: journaldir in Command line code on line 11

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in Command line code on line 12
    

From the above output in the Alfred Debugger, you can see that there are two problems:

  1. Line 11 has a variable, journaldir, that is undefined. It’s undefined because it is suppose to be journalDir. Variable name mistyping is the cause of many program bugs.
  2. The date() function requires that the time zone be set. To remove it, simply set the timezone. But, since accurate time reporting is not needed for the functionality of the date function being used, it would be much easier to ignore the error. You can tell PHP to ignore it by adding error_reporting(0); to the top of the script.

Once these two areas are fixed, the Script Filter now runs as expected!

Tip: Another area that creates problems with Alfred scripts are the environment variables. Alfred executes the scripts quickly, without a login shell. What that means is the shell processor does not run the startup scripts (ie: .bashrc for a bash shell or .zshrc for a zsh shell). Therefore, the paths to executables and other environment variables are not set properly. You have to take that into consideration when writing your scripts and debugging them.

Showing Block Outputs

Not only can problems be debugged, but the debugger can show what each block passes to the next block. Create some data to see by using t:newjournal to create a new journal called medical.

Activate the debugger and select the t:doing command. In the Alfred prompt, type t:doing. It will give you a choice of journals to add an entry. Select the medical.txt journal and type the message I have been very dizzy.

Output of the tdoing Command
Output of the t:doing Command

Pressing Return, the above is outputted to the debugger. It shows what the block sent to the next block. This is a handy way to see how a workflow works. It is also a great way of making sure the block is sending what you think it should be sending.

Stepping Through a State Machine

In the Alfred Workflows for Advanced, writing state machines in the Script Filter blocks was explored. In order to properly debug a state machine, it is necessary to see the current state. You can explore this in the t:addweekdaytask command.

An echo “Current state: $opt \n”; line was was added to the script of the t:addweekdaytask Script Filter to show what is the current state. Normally, the debugger only shows the xml output of the Script Filter if it has a problem. Since echoing the state to the output will break the xml formatting, it will display that information.

Looking at a State Machine Output - State 1
Looking at a State Machine Output - State 1

By typing t:addweekdaytask in the Alfred prompt produces the above output in the debugger. The echo statement tells that it is in the first state and shows the xml output. You can verify that the xml looks right and if the script formatted it correctly.

Looking at the State Machine Output - State 2
Looking at the State Machine Output - State 2

By typing t:addweekdaytask Tue|, the debugger shows that it is in state 2 and the xml for that state.

Future Developments

Speaking with Andrew, the creator of Alfred, revealed that new feactures are being added to the debugger continually. Many Alfred Forums participants are contributing ideas. Andrew is planning to add the displaying of all xml output from a Script Filter, not just when it bombs. He is also adding a Copy button to copy the output to the clipboard.

Conclusion

Since every bug is different, there is no way to show how to debug every type of problem. With the Alfred debugger, however, you can now see the things that were covered up in the sub-process execution of the scripts. 

Using this tool, you can now set out and find those pesky bugs!

Advertisement