Error nodes
Two nodes for handling errors: Try Catch, a control-flow fork node (architecturally
similar to Branch/Switch/Sequence — its own emit() is a
defensive stub, and the real compilation happens in the shared exec-chain
walker), and Throw, an ordinary exec-passthrough
statement node.
Usable both on the main canvas and inside a Function Graph.
Try Catch — error.tryCatch
Runs "Try Body"; if anything in it throws, execution jumps to "Catch Body" instead, with the thrown value available on the "Error" output pin. Optionally, check "Add Finally Statement" to add a third path, "Finally," that always runs after Try Body/Catch Body — whether or not anything actually threw.
Default — no Finally arm
"Add Finally Statement" checked
- Inputs:
in(exec) — "In" - Outputs:
try(exec) — "Try Body";catch(exec) — "Catch Body";finally(exec, only shown when "Add Finally Statement" is checked) — "Finally";error(value) — "Error" - Config fields: "Add Finally Statement" checkbox (off by default) — reveals the "Finally" execution pin
- Constraints: at least one of Try Body/Catch Body/Finally must have an outgoing wire; the "Error" pin can only be read from inside the Catch Body arm — wiring it into Try Body, Finally, a sibling branch, or anything outside the Catch arm is rejected at validation time.
try {
// ...Try Body arm
} catch (err_abc123) {
console.log(err_abc123); // "Error" reads the caught value
// ...rest of Catch Body arm
} finally {
// ...Finally arm — always runs, whether or not anything threw
}
Unlike Branch's optional else or Switch's optional default, the catch block is
always emitted, even if Catch Body is left completely unwired — a JavaScript try
statement requires one. The finally block, on the other hand, follows the same
"unwired optional arm = no-op" convention as Branch's else: check the box but leave the
Finally pin unwired and no finally clause is generated at all. Each arm gets its own
scope, exactly like Branch/Switch: a value computed inside Try Body can't be read from
Catch Body, Finally, or from outside the node.
Use case: Wrap risky logic — a JSON parse, a lookup that might come back empty, a call to something that can throw — and handle the failure explicitly instead of letting it crash the request. Add a Finally arm when you need guaranteed cleanup — closing a resource, logging that an operation finished — regardless of whether it succeeded or was caught.
Throw — error.throw
Throws whatever is wired (or typed as a literal) into "Value", then — if the throw somehow doesn't propagate further up — continues to "Next".
- Inputs:
in(exec) — "In";value(value) — "Value" - Outputs:
out(exec) — "Next" - Config fields: none — an unwired "Value" is typed directly on the pin
- Constraints: "Value" must be either wired or given a literal
throw new Error("something failed");
Wire in a Get Variable bound to an error-typed variable, or a Try Catch's own "Error" output (to re-throw inside a Catch Body), or type a plain string literal directly on the pin.
Use case: Reject a request with a specific error — for example, re-throwing inside a Catch Body after logging it, or throwing a validation failure before any other logic runs.
The "Error" variable type
Variables (see Error in the Variables section) can be declared
with data type error, which emits new Error(<message>) — the default value you type
becomes the message, JSON.stringify-ed the same way a string variable's default is.
Leaving the default empty emits a plain new Error() with no arguments. Works with Get
Variable/Set Variable exactly like any other data type.
let myError = new Error("initial error");
Use case: Store a reusable error (with a fixed message) in a variable, then throw it from a Throw node wherever it's needed, instead of typing the same message inline every time.