How do I safely extract the ok or error value from a Result?
← Safe Value Access · Ref: Q164
EK9 Results require compiler-enforced guards before accessing ok or error values. The isOk() guard unlocks .ok(), and the isError() guard unlocks .error(). Neither unlocks the other.
ISOK GUARD THEN OK
Check isOk() before accessing the ok value:
if r.isOk() okVal <- r.ok()
The compiler verifies isOk() was checked before allowing .ok().
ISERROR GUARD THEN ERROR
Check isError() before accessing the error value:
if r.isError() errVal <- r.error()
DUAL GUARD PATTERN
Handle both sides independently:
if r.isOk() process(r.ok()) else if r.isError() handleError(r.error())
OKORDEFAULT AND ERRORORDEFAULT
Extract with a fallback, no guard needed:
okVal <- r.okOrDefault("fallback") errVal <- r.errorOrDefault(-1)
Always returns a usable value.
TERNARY GUARD
Compact single-expression extraction:
okVal <- r.isOk() <- r.ok() else "default" errVal <- r.isError() <- r.error() else 0
See Q48 for Result basics. See Q86 for Result guard patterns. See Q87 for Result operations and callbacks.
Example
defines module qa.safeaccess.resultsafe defines function getOkResult() <- rtn <- Result("Success", Integer()) getErrorResult() <- rtn <- Result(String(), 42) defines program ResultExtractDemo() stdout <- Stdout() // === ISOK GUARD THEN OK === r1 <- getOkResult() if r1.isOk() okVal <- r1.ok() stdout.println(`Ok value: ${okVal}`) // === ISERROR GUARD THEN ERROR === r2 <- getErrorResult() if r2.isError() errVal <- r2.error() stdout.println(`Error value: ${errVal}`) // === DUAL GUARD PATTERN === r3 <- getOkResult() if r3.isOk() stdout.println(`Dual ok: ${r3.ok()}`) else if r3.isError() stdout.println(`Dual error: ${r3.error()}`) // === ? OPERATOR (SHORTHAND FOR ISOK) === r4 <- getOkResult() if r4? stdout.println(`? guard ok: ${r4.ok()}`) // === OKORDEFAULT / ERRORORDEFAULT === r5 <- getOkResult() safeOk <- r5.okOrDefault("fallback") stdout.println(`okOrDefault (ok result): ${safeOk}`) r6 <- getErrorResult() safeOk2 <- r6.okOrDefault("fallback") stdout.println(`okOrDefault (error result): ${safeOk2}`) safeErr <- r6.errorOrDefault(-1) stdout.println(`errorOrDefault: ${safeErr}`) // === TERNARY GUARD === r7 <- getOkResult() ternaryOk <- r7.isOk() <- r7.ok() else "default" stdout.println(`Ternary ok: ${ternaryOk}`) r8 <- getErrorResult() ternaryErr <- r8.isError() <- r8.error() else 0 stdout.println(`Ternary error: ${ternaryErr}`)
Common mistakes
E50060 — Result does not have an isValid() method. The correct method for checking the success state is isOk(). Calling a non-existent method triggers E50060 — method not resolved. See ek9 -h E50060 for details.
Incorrect:
if r1.isValid()
Correct:
if r1.isOk()
Other ways to ask this
- How do I unwrap a Result in EK9?
- What is the safe way to access Result ok and error values?
- How do I get the success or failure value from a Result in EK9?
Coming from another language?
Java: try-catch for error handling, no Result type, exceptions can be silently ignored. Python: try/except, no compile-time enforcement. Rust: Result.unwrap() panics, pattern matching enforced by compiler. Go: val, err := fn(); if err != nil is convention not enforcement. Kotlin: Result.getOrElse() for defaults, no compile-time guard enforcement. EK9: isOk()/isError() are compiler-enforced guards, okOrDefault()/errorOrDefault() for safe defaults, no escape hatches.
Keywords: error, okOrDefault, isset, access, debug, ok, null-safe, isError, safe, result, unwrap, extract, guard, isOk, default