Guard a try block so it only runs when the guard value is set.

← Control Flow · Ref: Q1157

try with guard — body runs only if guard value is set:

  try mainValue <- setValue
    stdout.println(mainValue)
  catch
    -> e as Exception
    stdout.println(e.reason())
  finally
    stdout.println("cleanup")

If setValue is unset, the WHOLE try statement is skipped: the body, catch AND finally. The guard gates the statement as it gates an if. Once the guard is set and the try is entered, finally always runs. Put cleanup that must run whatever the guard gives outside the guarded try.

See Q1146 for if-guard. See Q1154 for basic try/catch.

Example

defines module qa.controlflow.tryguardexpression

  defines function

    lookup()
      -> available as Boolean
      <- rtn as Integer: Integer()
      if available
        rtn: 42

  defines program

    TryGuardExpressionDemo()
      stdout <- Stdout()

      //Set guard — try body executes
      setValue <- lookup(true)
      try mainValue <- setValue
        stdout.println(`Try body: ${mainValue}`)
      catch
        -> e as Exception
        stdout.println(e.reason())
      finally
        stdout.println("Finally: runs once the try is entered")

      //Unset guard — the whole try is skipped, finally included
      unsetValue <- lookup(false)
      try skipped <- unsetValue
        stdout.println(`Body: never printed ${skipped}`)
      catch
        -> e as Exception
        stdout.println("Catch: never printed")
      finally
        stdout.println("Finally: never printed")
      stdout.println("After the unset guard: whole try skipped")

Common mistakes

E01073 — EK9 has no null literal — 'setValue <- null' is rejected outright; use tri-state semantics (an unset value like Integer()) with the '?' operator instead. See ek9 -h E01073 for details.

Incorrect:

setValue <- null

Correct:

setValue <- lookup(true)
Other ways to ask this
  • I need the try body to execute only if a value is present
  • In Swift I'd use 'guard let'. Show the EK9 try guard equivalent
  • Given a possibly-unset value, wrap the try block with a guard assignment
  • Skip the try body entirely when the guard variable is unset
  • Does finally still run when the try guard is unset?

Coming from another language?

Swift: guard let value = optional else { return }. Kotlin: value?.let { }. EK9: try value <- expr — guard on the try itself; an unset guard skips the whole try, finally included.

Keywords: unset, set, try, conditional, skip, guard