Errores irrecuperables
Para crear errores que paren completamente la ejecución del programa usamos el
macro panic!()
. Entre los paréntesis podemos dar una pequeña descripción del
problema, con la sintaxis del macro format!()
(o println!()
).
Errores recuperables
Para otros errores donde una operación pudo acabar de forma exitosa, usamos la
enum Result
:
La variante Ok
guarda el resultado de la función en caso de que la operación
fuese exitosa. Sino, se provee un error con la variante Err
.
Podemos manejar el error de la siguiente forma:
1let f = match File::open("hello.txt") {
2 Ok(file) => file,
3 Err(error) => match error.kind() {
4 ErrorKind::NotFound => match File::create("hello.txt") {
5 Ok(fc) => fc,
6 Err(e) => panic!("Problem creating the file: {:?}", e),
7 },
8 other_error => {
9 panic!("Problem opening the file: {:?}", other_error)
10 }
11 },
12};
Para evitar tanta expresión match
podemos usar la función unwrap_or_else()
,
que devuelve el valor en caso de éxito y ejecuta la función que le demos de
parámetro en caso de error:
1let f = File::open("hello.txt").unwrap_or_else(|error| {
2 if error.kind() == ErrorKind::NotFound {
3 File::create("hello.txt").unwrap_or_else(|error| {
4 panic!("Problem creating the file: {:?}", error);
5 })
6 } else {
7 panic!("Problem opening the file: {:?}", error);
8 }
9});
De igual forma esto es muy largo para escribir, y sobre todo si estamos probando. Para eso tenemos otras funciones que nos simplifican más el trabajo.
unwrap()
devuelve el valor delOk
en caso de éxito y llama apanic!()
en caso contrario.expect(String)
es exactamente lo mismo, solo que nos permite añadir una pequeña descripción del error.
Para simplificar más, y en el caso de estar escribiendo una función que puede
dar un error o no, podemos simplemente propagarlo, que sería devolverlo para que
el que use esta función se encargue del error. Podemos devolver el error
manualmente o usar el operador ?
: