How does an EK9 program set its exit status?
← Error Handling and Exceptions · Ref: Q1431
An EK9 program ends with exactly one exit status, and only four things decide it. There is no exit() call to reach for in the middle of the code.
1. A NORMAL END is 0. A program that declares no return and finishes exits 0.
2. A RETURNED Integer is the status. A program may declare a return, and it must be an Integer (anything else is E07590). The value it holds when the program finishes is the exit status, and an UNSET return exits 1. The application teardown runs first, and then the program exits with that status. The program below ends with 'exitCode: invalid > 0 <- 2 : 0', so it exits 2 when it finds invalid input and 0 when it does not.
3. An Exception NOTHING CATCHES ends the program with that exception's own exit code, or 1 when it has none. Exception("No settings file named", 3) exits 3. The finally blocks and the application teardown run first. See Q1432 and Q1433.
4. A Panic always exits 1. A Panic is raised only by the language: a failed require, a constrained-type value out of range, or an unset for-range bound. You cannot throw one or choose its code. See Q1434 and Q1435.
WHICH ONE TO USE
Return an Integer when the program finishes its work and reports an outcome, such as 2 for 'some records were invalid'. Throw an Exception with a code, and do not catch it, when the program cannot go on and you want the caller to see a particular failure status. Use require for programming errors. Every require failure exits 1, so it is not a way to report an outcome.
THE ek9 COMMAND HAS ITS OWN CODES
Compiling can fail before your program ever runs, and the ek9 command then exits with its own code, for example 8 when compilation fails. Your program's codes share those numbers. See Q1437 for how to tell them apart.
See Q888 for why a program may only return an Integer. See Q136 for throwing exceptions.
Example
defines module qa.errorhandling.programexitstatus defines function countInvalid() -> quantities as List of Integer <- rtn as Integer: 0 for quantity in quantities if quantity < 0 rtn++ defines program ExitStatusDemo() <- exitCode as Integer? stdout <- Stdout() invalid <- countInvalid([3, 7, 12]) stdout.println(`Invalid quantities: ${invalid}`) exitCode: invalid > 0 <- 2 : 0 stdout.println(`Exiting with status: ${exitCode}`)
Common mistakes
E07590 — A program's return value is its exit status, so it can only be an Integer. Return 0 for success and a non-zero Integer for a failure you want the caller to see. See ek9 -h E07590 for details.
Incorrect:
<- exitCode as Boolean?
Correct:
<- exitCode as Integer?
Other ways to ask this
- How do I return a non-zero exit code from an EK9 program?
- What exit code does my EK9 program end with?
- Is there a System.exit or sys.exit in EK9?
- How do I make my program fail a shell script or CI step?
Coming from another language?
Java: System.exit(n) from anywhere, or an uncaught exception exits 1. C: return n from main, or exit(n). Python: sys.exit(n) raises SystemExit. Go: os.Exit(n), which skips deferred calls. Rust: std::process::exit(n), or main returns Result. EK9: no exit call at all. The status comes from the program's return value, the exit code of an uncaught Exception, or a Panic (always 1), and finally blocks and teardown always run first.
Keywords: program, System.exit, Integer, exit, exit code, sys.exit, CI, exit status, shell, return code