Cairo ofrece técnicas de manejo de errores para resolver problemas y gestionar los errores, lo que permite que el código se ejecute sin problemas durante su ejecución.
En Cairo hay dos tipos de errores:
panic: estos errores terminan el programa de inmediato.Result: estos errores se pueden manejar durante la ejecución.panic
En Cairo pueden surgir problemas inesperados durante la ejecución del programa, lo que da lugar a errores en tiempo de ejecución llamados «panics».
Esto detiene la ejecución del programa, lo cual es útil cuando continuar no tendría ningún sentido.
Un panic puede ocurrir de forma accidental, por acciones que hacen que el código entre en panic (por ejemplo, acceder a un array más allá de sus límites), o de forma deliberada, llamando a la función panic.
fn main() {
let data = array![1, 2];
if true {
panic(data);
}
println!("This line will not be reached.");
}
Si ejecutas este ejemplo, se imprimiría lo siguiente en la consola:
Run panicked with [1, 2, ].
También existe una macro especial, llamada panic!, que permite usar un ByteArray como mensaje de error.
panic!("The error for the panic! Error message is not limited to 31 characters anymore");
assert!
La macro assert! es una herramienta útil para hacer cumplir condiciones específicas en tu código.
Si la condición en assert! se evalúa como false, el programa entrará en panic con un mensaje de error de tipo ByteArray.
A menudo se usa para verificar suposiciones durante el desarrollo y asegurar que los valores cumplan ciertos criterios.
Por ejemplo:
fn main() {
let x = 5;
assert!(x > 0, "x must be greater than zero");
}
Si x no es mayor que cero, el programa entrará en panic con el mensaje "x must be greater than zero".
assert! es útil para comprobar invariantes y precondiciones sin escribir manualmente código de manejo de errores.
nopanic
La notación nopanic de Cairo indica que una función nunca entrará en panic.
fn function_never_panic() -> felt252 nopanic {
108
}
A una función nopanic solo se la puede llamar desde una función que también esté anotada como nopanic.
panic_with
El atributo panic_with de Cairo sirve para marcar una función que devuelve un Option o un Result, y crea un envoltorio para tu función anotada que entrará en panic si la función devuelve Option::None o Result::Err.
#[panic_with('value is 0', wrap_not_zero)]
fn check_not_zero(value: u128) -> Option<u128> {
if value == 0 {
Option::None
} else {
Option::Some(value)
}
}
fn main() {
check_not_zero(0); // -> returns Option::None
wrap_not_zero(0); // -> panics with 'value is 0'
}
Result
La enumeración Result gestiona los errores de forma controlada, ofreciendo información en lugar de fallar o producir un comportamiento indefinido.
enum Result<T, E> {
Ok: T,
Err: E,
}
Veamos un ejemplo de cómo podríamos usar esta enumeración para manejar una división por cero:
fn divide(a: u32, b: u32) -> Result<u32, ByteArray> {
if b == 0 {
return Result::Err("Error: Division by zero"); // Return an error if division by zero is attempted
}
Result::Ok(a / b)
}
fn main() {
// Test with division by zero
match divide(10, 0) {
Result::Ok(result) => println!("Division successful: {}", result),
Result::Err(e) => println!("{}", e),
}
}
?
El operador ? se usa para un manejo de errores conciso e implícito, y deja que la función que llama se encargue de cualquier error que pueda ocurrir.
Cuando usas el operador ? en un tipo Result u Option, hace lo siguiente:
Result::Ok(x) u Option::Some(x), devuelve directamente el valor interno x.Result::Err(e) u Option::None, propaga el error o None regresando de inmediato desde la función.fn parse_u8(s: felt252) -> Result<u8, felt252> {
match s.try_into() {
Option::Some(value) => Result::Ok(value),
Option::None => Result::Err('Invalid integer'),
}
}
fn do_something_with_parse_u8(input: felt252) -> Result<u8, felt252> {
let input_to_u8: u8 = parse_u8(input)?;
// DO SOMETHING
let res = input_to_u8 - 1;
Result::Ok(res)
}
fn main() {
let number: felt252 = 258;
match do_something_with_parse_u8(number) {
Result::Ok(value) => println!("Result: {}", value),
Result::Err(e) => println!("Error: {}", e),
}
}