How do I verify that code does not throw an exception in EK9?

← Error Handling and Exceptions · Ref: Q307

EK9 provides assertDoesNotThrow as a built-in keyword for verifying that an expression completes without throwing any exception. It is only valid inside @Test programs.

SYNTAX

assertDoesNotThrow(expression)
The test passes if the expression completes normally. The test fails if any exception is thrown.

USAGE

Use assertDoesNotThrow to verify no exception occurs:

  assertDoesNotThrow(safeFunction())

If safeFunction() throws, the test fails with structured diagnostic output.

FAILURE OUTPUT

When assertDoesNotThrow fails, EK9 provides structured output:

  assertDoesNotThrow FAILED
    Location: ./dev/tests.ek9:5:3
    Expression: riskyFunction()
    Expected: No exception
    Actual: org.ek9.lang::Exception
    Message: Division by zero

The output includes the exception type and message, captured at compile time from the AST.

WHEN TO USE

assertDoesNotThrow is valuable when:
- Testing boundary conditions that should not throw (edge cases).
- Verifying error recovery leaves the system in a stable state.
- Testing that previously throwing code has been fixed.
- Documenting in tests that certain operations are safe.

ASSERTTHROWS VS ASSERTDOESNOTTHROW

assertThrows(ExceptionType, expr): Verifies an exception IS thrown. Can capture the exception.
assertDoesNotThrow(expr): Verifies NO exception is thrown.
Both are compile-time restricted to @Test programs.

See Q306 for assertThrows. See Q305 for require vs assert vs throw. See Q156 for basic assertions. See Q209 for exception testing patterns.

Example

defines module qa.errorhandling.assertdoesnot

  defines function

    <?-
      A safe division that returns Result instead of throwing.
      Used to demonstrate safe operations.
    -?>
    safeDivide()
      ->
        a as Integer
        b as Integer
      <-
        rtn as Integer: 0

      if b == 0
        throw Exception("Division by zero")
      rtn: a / b

    <?-
      Safe string processing that never throws.
    -?>
    processName() as pure
      -> name as String
      <- rtn as String: `Hello, ${name}!`

  defines program

    @Test
    AssertDoesNotThrowStatementTest()
      stdout <- Stdout()

      stdout.println("=== assertDoesNotThrow as statement ===")

      assertDoesNotThrow(processName("EK9"))
      stdout.println("Verified: processName does not throw")

      assertDoesNotThrow(safeDivide(10, 2))
      stdout.println("Verified: safeDivide(10, 2) does not throw")

    @Test
    AssertDoesNotThrowMultipleTest()
      stdout <- Stdout()

      stdout.println("=== multiple assertDoesNotThrow checks ===")

      assertDoesNotThrow(processName("World"))
      stdout.println("Verified: processName(\"World\") is safe")

      assertDoesNotThrow(safeDivide(100, 5))
      stdout.println("Verified: safeDivide(100, 5) is safe")

      assertDoesNotThrow(safeDivide(0, 1))
      stdout.println("Verified: safeDivide(0, 1) is safe")

Common mistakes

E08091 — The parameter name is declared but never used in the function body. All parameters must be referenced. See ek9 -h E08091 for details.

Incorrect:

processName() as pure
      -> name as String
      <- rtn as String: "Hello!"

Correct:

processName() as pure
      -> name as String
      <- rtn as String: `Hello, ${name}!`
Other ways to ask this
  • How does assertDoesNotThrow work in EK9?
  • How do I test the happy path does not throw?
  • What is the EK9 equivalent of JUnit assertDoesNotThrow?

Coming from another language?

Java: JUnit assertDoesNotThrow(() -> code) wraps Executable. Python: no built-in equivalent, just run the code and let pytest catch unexpected exceptions. Rust: no equivalent, tests fail on panic by default. Go: no equivalent, tests fail on unrecovered panic. Kotlin: assertDoesNotThrow { code } from kotlin.test. EK9: assertDoesNotThrow(expression) is a built-in keyword, compile-time restricted to @Test programs, with structured failure output including exception type and message.

Keywords: diagnostic, safe, catch, test, assertDoesNotThrow, happy path, exception, testing, no throw, handle, verify