Flow Studio
Submit vs. Cancel Routing
How submitPort and cancelPort direct execution flow based on whether the user submitted or cancelled the form.
Port Routing Logic
The resume API receives an action field that determines which port fires:
| Action | Port Fired | Data Available |
|---|---|---|
"submit" | submitPort (default: "main") | Full form field values |
"cancel" | cancelPort (default: "cancelled") | { _action: "cancel", _cancelledBy, _cancelledAt } |
"timeout" | timeoutPort (default: "timeout") | { _action: "timeout", _timedOutAt } |
Canvas Layout for Three Paths
┌───────────────────┐
│ expenseReview │
│ (UserFormNode) │
└──────┬────────────┘
│ ┌─────────────────┐
├─ submitted ──▶ ProcessApproval │
│ └─────────────────┘
│ ┌─────────────────┐
├─ cancelled ──▶ NotifyCancelled │
│ └─────────────────┘
│ ┌─────────────────┐
└─ timeout ────▶ EscalateToAdmin │
└─────────────────┘
Custom Action Names
If the form has a custom submit button (e.g., "Request More Info" alongside "Approve"), you can define multiple submit actions:
{
"submitActions": [
{ "action": "approve", "label": "Approve", "port": "approved" },
{ "action": "reject", "label": "Reject", "port": "rejected" },
{ "action": "requestInfo", "label": "Request More Info", "port": "infoRequested" }
]
}
Each action sends a different action value in the resume payload, routing to the corresponding port.
Always handle cancel: Connect the
cancelPort to a meaningful handler. If the user cancels and there is no connected edge, the workflow branch silently terminates with no cleanup, no notification, and no audit entry. This is almost always undesirable.