Error Handling
Nyx provides try/catch for recoverable errors and panic for unrecoverable ones. The throw built-in raises a catchable string error, while panic terminates the program unless caught in a surrounding try block.
Code
// Manejo de errores: try/catch con throw y panic
fn dividir(a: int, b: int) -> int {
if b == 0 {
throw("division por cero: denominador es 0")
}
return a / b
}
fn main() -> int {
// Capturar un throw explícito
var resultado: String = ""
try {
let r: int = dividir(10, 0)
resultado = int_to_string(r)
} catch(e: String) {
resultado = "Error capturado: " + e
}
print(resultado)
// try normal (sin error)
var ok: String = ""
try {
let r: int = dividir(20, 4)
ok = "resultado: " + int_to_string(r)
} catch(e: String) {
ok = "inesperado: " + e
}
print(ok)
// Capturar panic
var panic_msg: String = ""
try {
panic("algo salio muy mal")
} catch(e: String) {
panic_msg = "panic atrapado: " + e
}
print(panic_msg)
// try anidado
var externo: String = ""
try {
try {
throw("error interno")
} catch(e: String) {
externo = "manejado: " + e
}
} catch(e: String) {
externo = "no deberia llegar aqui"
}
print(externo)
return 0
}
Output
Error capturado: division por cero: denominador es 0 resultado: 5 panic atrapado: algo salio muy mal manejado: error interno
Explanation
throw(msg) raises an error that unwinds the stack until the nearest enclosing catch clause. The caught value e is typed as String, matching whatever was passed to throw. When no error occurs the catch block is skipped entirely, so the dividir(20, 4) call goes straight to its result.
panic signals an unrecoverable condition — by default it aborts the process, but it too can be caught with try/catch when recovery is genuinely possible. This makes it useful for assertions during development that can be wrapped in tests.
Nested try blocks allow inner errors to be handled locally without propagating to outer handlers. In the final example the inner catch handles "error interno" completely, so the outer catch is never reached.