soma.cell

E0117: await

E0117 await — an await stands where its handler could not be stopped and resumed: outside a [task] handler, or not as a whole statement of its body or of an if branch there.

A compile-time error of soma check, the checker of the Soma programming language (soma explain E0117).

The rule

await approve(…), await signal(…) and await sleep(…) are durable waits: the handler stops, what it wrote so far commits, and the rest runs when the answer arrives, even after a restart. Only a [task] handler is made of such steps, so soma check reports E0117 for an await in any other handler, and also for an await that is not a whole statement of the handler's body or of an if branch (inside a loop, or inside a larger expression). Mark the handler [task] after its parameter list: on refund(id: String, amount: Int) [task] { … }.

A program that triggers it

wrong.cell

cell Refunds {
    face {
        signal refund(id: String, amount: Int) -> Map
    }
    state flow {
        initial: requested
        requested -> pending
        pending -> paid
        pending -> refused
    }
    on refund(id: String, amount: Int) {
        transition(id, "pending")
        let ok = await approve("refund {amount} for {id}")
        if !ok {
            transition(id, "refused")
            return map("refused", id)
        }
        transition(id, "paid")
        return map("paid", id)
    }
}

What soma check prints:

$ soma check wrong.cell
error: `await approve(…)` in handler 'refund', which is not `[task]`: a wait ends a step (what was written so far commits, the rest runs when the answer arrives) and only a `[task]` handler has steps — write `on refund(…) [task] { … }`
  --> wrong.cell:13:18
   |
13 |         let ok = await approve("refund {amount} for {id}")
   |                  ^
  = code: E0117
✗ 1 error(s), 0 warning(s).

The fix field of soma check --json: write `on refund(…) [task] { … }`

On line 11, on refund(id: String, amount: Int) { becomes on refund(id: String, amount: Int) [task] {.

wrong.cell → right.cell

--- wrong.cell
+++ right.cell
@@ -9,5 +9,5 @@
         pending -> refused
     }
-    on refund(id: String, amount: Int) {
+    on refund(id: String, amount: Int) [task] {
         transition(id, "pending")
         let ok = await approve("refund {amount} for {id}")

With the fix, soma check accepts the program:

$ soma check right.cell
✓ All checks passed.