#!/usr/bin/env catnip
# try/except/finally basics
# Catch a specific exception type
try {
1 / 0
} except {
e: ZeroDivisionError => { print("caught: " + e) }
}
# ⇒ caught: division by zero
# Multiple handlers with type union
try {
x = undefined_var
} except {
e: TypeError => { print("type error") }
e: ValueError | KeyError => { print("value or key") }
_ => { print("something else") }
}
# ⇒ something else
# Finally block: always executes
x = 0
try {
x = 42
} finally {
print("cleanup: x = " + str(x))
}
# ⇒ cleanup: x = 42
# Raise an exception
try {
raise "invalid input"
} except {
e: RuntimeError => { print("got: " + e) }
}
# ⇒ got: invalid input
# Re-raise in except
try {
try {
1 / 0
} except {
_ => {
print("logging error")
raise
}
}
} except {
e: ZeroDivisionError => { print("outer caught: " + e) }
}
# ⇒ logging error
# ⇒ outer caught: division by zero
# Hierarchical matching: parent type catches children
try {
1 / 0
} except {
e: ArithmeticError => { print("arithmetic: " + e) }
}
# ⇒ arithmetic: division by zero
# Exception catches everything
try {
raise ValueError("bad input")
} except {
e: Exception => { print("caught: " + e) }
}
# ⇒ caught: bad input
# Specific before general: first match wins
try {
1 / 0
} except {
e: ZeroDivisionError => { print("specific") }
e: ArithmeticError => { print("general") }
e: Exception => { print("catchall") }
}
# ⇒ specific