Exceptions and Resource Safety
Klyn uses exceptions for exceptional failures, API boundary contracts, and resource cleanup.
This page covers throw, try, catch,
finally, and the language form that manages auto-closable resources.
if value == 0:
throw ZeroDivisionException("division by zero")
try:
riskyOperation()
catch e as Exception:
print(e.message)
A catch block may bind the exception to a local name with catch e as Exception:.
The exception name and variables first declared in that block are local to the catch block.
Declare state before the try when both successful and exceptional paths must update it.
import klyn.io
status = "pending"
try:
loadConfiguration()
status = "loaded"
catch e as IOException:
status = "failed"
diagnostic = e.message
print(status)
# print(e) # TypeError: e belongs to the catch block.
# print(diagnostic) # TypeError: diagnostic belongs to the catch block.
try:
writer.writeLine("hello")
finally:
writer.close()
Use finally for cleanup that must happen whether the protected code succeeds or not.
A finally block can use variables declared in an enclosing scope, but it cannot read
locals owned by the sibling try or catch blocks.
try resource = Resource():
resource.doWork()
finally:
print("resource is closed here")
The try resource = ...: form is the language-level resource-management construct.
It is the preferred pattern when the value implements AutoClosable.
throws
public class Parser:
public parse(value as String) as Int throws ValueException:
throw ValueException("invalid value")
Use throws when the API contract should make an exceptional path explicit.
ValueException is the canonical exception for a value that is outside the
accepted domain or cannot be converted to the requested type.
- Throw typed exceptions with messages that explain the failure condition clearly.
- Prefer resource-aware
trysyntax over manual cleanup when possible. - Do not use exceptions for ordinary branching that can be represented by normal control flow.