Error Handling
Runtime faults are caught and mitigated gracefully via structured exception blocks.
Try-Catch-Finally Blocks
The error handling block uses try, catch [variable], finally, and finishes with end:
try
let num = 1 / 0
catch error
print("Caught an error: " + str(error))
finally
print("Cleanup: This block always executes.")
end
Try-Finally (No Catch)
You can omit the catch block and just use try/finally for resource cleanup:
try
let f = "file_handle"
# use resource...
finally
print("cleaned")
end
Try-Catch (Ignoring Error)
If you don't need the error variable, you can omit it and use catch end:
try
file.delete("temp.txt")
catch end
Finally with Return
The finally block runs even when a return statement is executed in the try block:
fn testReturn()
try
return 42
finally
print("cleanup runs before return")
end
end
print(testReturn()) # prints "cleanup runs before return" then 42
Nested Try-Catch Order
When nesting try-catch blocks, the inner catch handles the error first. If it re-throws, the outer catch handles it:
try
try
throw "inner error"
catch e
print("Inner caught: ${e}")
throw e # re-throw to outer
end
catch e
print("Outer caught: ${e}")
end
Throwing Exceptions
Raise custom errors using the throw keyword. You can throw simple strings or complex payload Maps:
fn validateAge(age)
if age < 0
throw {"error": "InvalidAge", "message": "Age cannot be negative"}
end
end
try
validateAge(-1)
catch err
print("Error Code: " + err["error"]) # => InvalidAge
end