How do I throw exceptions in EK9?
← Error Handling and Exceptions · Ref: Q136
EK9 uses the throw keyword to raise exceptions. You can throw the built-in Exception or create custom exception types by extending Exception.
CREATING EXCEPTIONS
Create an Exception with a reason string:
ex <- Exception("Something went wrong")
Or with a reason and exit code:
ex <- Exception("Fatal error", 1)
The exit code is used if the exception propagates to the program entry point.
THROW KEYWORD
Throw an exception variable:
ex <- Exception("Error occurred") throw ex
The throw statement must reference a variable, not an inline expression.
CUSTOM EXCEPTION TYPES
Define custom exceptions by extending Exception:
ValidationError extends Exception field <- String() ValidationError() -> reason as String field as String super(reason) this.field :=: field field() as pure <- rtn as String: field default operator ?
Custom exceptions can carry additional context beyond the reason string.
EXCEPTION PROPERTIES
All exceptions have:
ex.reason() the error message ex.exitCode() optional exit code $ex string representation ex? isSet check
WHEN TO THROW
Throw exceptions for truly unexpected, exceptional conditions:
- Invalid arguments that indicate programmer error
- System failures (I/O errors, resource unavailability)
- Broken invariants that should never occur
For expected failures (validation, missing data), prefer the Result type instead.
See Q134 for try/catch. See Q138 for catching specific exception types. See Q139 for choosing between try/catch and Result.
See Q304 for require preconditions. See Q305 for require vs assert vs throw.
Example
defines module qa.errorhandling.throwexception defines class <?- Custom exception for validation errors with field name context. -?> ValidationError extends Exception field <- String() ValidationError() -> reason as String field as String super(reason) this.field :=: field field() as pure <- rtn as String: field default operator ? defines function validateAge() -> age as Integer <- rtn <- String() if age < 0 ex <- ValidationError("Age cannot be negative", "age") throw ex maxAmount <- 150 if age > maxAmount ex <- ValidationError("Age unreasonably large", "age") throw ex rtn: "Valid age: " + $age defines program ThrowExceptionDemo() stdout <- Stdout() // === THROWING BUILT-IN EXCEPTION === try ex <- Exception("Something went wrong") throw ex catch -> ex as Exception stdout.println("Caught: " + ex.reason()) // === THROWING CUSTOM EXCEPTION === try result <- validateAge(-5) stdout.println(result) catch -> ex as ValidationError stdout.println(`Validation failed on field '${ex.field()}': ${ex.reason()}`) // === SUCCESSFUL PATH === try result <- validateAge(25) stdout.println(result) catch -> ex as ValidationError stdout.println("Should not reach here") // === EXCEPTION WITH EXIT CODE === try ex <- Exception("Fatal startup error", 1) throw ex catch -> ex as Exception stdout.println("Exit code: " + $ex.exitCode())
Common mistakes
E50060 — EK9 Exception has no getMessage() method. Use reason() to get the exception message. See ek9 -h E50060 for details.
Incorrect:
stdout.println("Caught: " + ex.getMessage())
Correct:
stdout.println("Caught: " + ex.reason())
E50060 — EK9 Exception uses exitCode(), not getExitCode(). EK9 does not use Java-style getter naming. See ek9 -h E50060 for details.
Incorrect:
stdout.println("Exit code: " + ex.getExitCode())
Correct:
stdout.println("Exit code: " + $ex.exitCode())
E50060 — The method is field(), not getField(). EK9 does not use Java-style getter naming conventions. See ek9 -h E50060 for details.
Incorrect:
stdout.println(`Validation failed on field '${ex.getField()}': ${ex.reason()}`)
Correct:
stdout.println(`Validation failed on field '${ex.field()}': ${ex.reason()}`)
E04030 — Only Exception types (or subtypes) can be thrown. Throwing a String triggers E04030 — type must be of Exception type. Wrap the message in an Exception constructor. See ek9 -h E04030 for details.
Incorrect:
ex <- "Something went wrong" throw ex
Correct:
ex <- Exception("Something went wrong") throw ex
E04030 — Only Exception types can be thrown in EK9. Throwing a String triggers E04030. Create an Exception with the message. See ek9 -h E04030 for details.
Incorrect:
ex <- "Fatal startup error" throw ex
Correct:
ex <- Exception("Fatal startup error", 1) throw ex
Other ways to ask this
- How do I raise an error in EK9?
- How do I create custom exceptions?
- How do I extend Exception in EK9?
Coming from another language?
Java: throw new SomeException("msg") with extends Exception or RuntimeException. Python: raise ValueError("msg") with class hierarchy. Rust: no throw, uses Result::Err() or panic!(). Go: no throw, uses error return values. Kotlin: throw SomeException("msg") like Java. Swift: throw SomeError() with Error protocol conformance, throws keyword required on function signatures. EK9: throw ex where ex is a variable (not inline new), custom exceptions use 'extends Exception' with additional fields, default operator ? required.
Keywords: catch, custom, extends, error, exception, throw, raise, reason, exitCode, handle, swift, create