Textflow Flow Control

Normally, processing of a Pipeline will simply flow from Command to Command, consecutively. However, Textflow does have very limited flow control capabilities, mostly for error handling.

Processing can “jump ahead” in the Pipeline two ways:

  1. From internal code in a Command. Some Commands are designed to look for specific locations in a Pipeline and move to them under certain conditions.
  2. Explicitly, using a specific Command.

Three Commands apply here:

Note that you cannot jump backwards in the Pipeline. You can only jump forward in the Pipeline. This prevents any chance of a circular reference.

Here’s a contrived example:

set -text:"This is my Working Text"
goto -label:future-command

# This will not be executed
append -text:!!!!
end

label -name:future-command
append -text:????

This Pipeline “jumps over” the append and end commands.

As noted, this is contrived and serves no real purpose. In reality, jumping forward in the Pipeline is most often used for error handling.

For example, the http command makes an HTTP request. All sorts of different things can go wrong when this happens, and you might want to handle different errors in different ways.

If the http Command fails, the code internal to that Command will look for a series of labels, and jump to the first one it finds. The labels it will try to find are (in order):

  1. http-error-[status code]
  2. http-error-[status code range]xx
  3. http-error
  4. error

Here’s an example of an http Command and multiple label Commands which denote error-handling logic based on what might have happened.

http -url:http://domain.com/some/path
end

label -name:http-error-401
set -text:"You are not authorized to access the content."
end

label -name:http-error-4xx
set -text:"The server responded, but was unable to find the content."
end

label -name:http-error-5xx
set -text:"The server reported an expected error."
end

label -name:http-error
set -text:"Something went wrong with the server request."
end

label -name:error
set -text:"There was an unspecified error."
end

Each end command effectively says, “Stop running commands and return whatever we have.”

If no errors occur, the first end (right after the http command) will return the body of the response, which is what we intended.

If there’s an error, that end command will never be executed, and instead, the http Command will jump the processing forward to one of the labels, which will set the Working Text to an appropriate message then end which will return whatever the message is.

Note that we had to include the end statements after the http and each set Command, because otherwise the flow would simply continue down through all the subsequent blocks. Each set of error logic is essentially bracketed by a label and an end.

If we wanted to enable consistent formatting of the error messages, instead of end, we could use jump-to to bring the flow back together.

label -name:http-error-404
set -text:"The content could not be found."
goto -label:format-error

# Insert all the other error handlers here, all jumping to "format-error" after setting the text

label -name:format-error
wrap -tag:div -style:"color:red;"

In this example, the flow has multiple options to pick from in an error occurs – several different blocks of logic “fan out” from the initial http command. Based on the error encountered, a label is selected, processing jumps to that point, and then it returns to a single location (meaning, it all comes back to format-error and whatever might follow it) and resumes its normal, consecutive flow.

flowchart TD
    1[http]:::good
A[end]:::good
B([output])
    2[http-error-401]:::error
    4[http-error-4xx]:::error
    5[http-error-5xx]:::error
    6[http-error]:::error
    7[error]:::error
    8[format-error]:::good
    9([output])

1-->A
A-->B
1--internal goto-->2-->a[set]--explicit goto-->8
1--internal goto-->4-->c[set]--explicit goto-->8
1--internal goto-->5-->d[set]--explicit goto-->8
1--internal goto-->6-->e[set]--explicit goto-->8
1--internal goto-->7-->f[set]--explicit goto-->8

8-->9

classDef error fill:#FFcccc,stroke:#333,stroke-width:1px;
classDef good fill:#ccffcc,stroke:#333,stroke-width:1px;

Conditional Goto

You might want branching constructs in your code. Textflow supports this in the form of goto Commands that will evaluate an expression.

# Set the "name" variable to "deane"
set -text:deane => name

# If "name" is "deane", jump forward
goto -if:"vars.name = 'deane'" -label:foo

# This will never be executed
end

label -name:foo
set -text:"We will always get here."

The expression is JSONata. Any JSONata expression that evaluates to true or false will work.

The variables will be stringified into JSON as an object called vars with individual properties for each variable. The working text will be available in an object called text.

Some more examples:

vars.age > 18

$contains($lowercase(text), 'foo')

$$match(vars.url, 'http://.*')

Review all the options in the JSONdata documentation for “Operators” and “Functions.”