Manejo de errores en Rust: try/catch y más allá

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: filosofía del manejo de errores en Rust



A diferencia de muchos lenguajes con excepciones (Java, Python, C++), Rust no utiliza la construcción clásica try/catch. En su lugar, el lenguaje ofrece un enfoque más explícito y type-safe. Los errores en Rust no son flujos de control ocultos, sino valores de retorno. Esto hace que el código sea predecible y protege contra fallos "silenciosos".



En Rust hay dos tipos principales para representar situaciones de error:

  • Result<T, E> — para errores recuperables (errores de entrada/salida, parsing, lógica de negocio).
  • Option<T> — para ausencia de valor (análogo a null, pero seguro).


En este artículo analizaremos cómo trabajar con estos tipos, cómo reemplazar el mundo de try/catch y cómo escribir código robusto en Rust.



1. Result<T, E>: la herramienta principal para el manejo de errores



El tipo Result es un enum con dos variantes: Ok(T) (éxito) y Err(E) (error). Se utiliza en la mayoría de las funciones que pueden fallar.



1.1. Creación y retorno de Result



use std::fs::File;use std::io::Read;

fn read_file(path: &str) -> Result<String, std::io::Error> { let mut file = File::open(path)?; // operador ? — análogo a try! let mut contents = String::new(); file.read_to_string(&mut contents)?; Ok(contents)}


Aquí el operador ? es un elemento clave. Funciona como try en otros lenguajes: si el resultado es Err, la función retorna inmediatamente ese error. Si es Ok, extrae el valor.



1.2. Manejo con match



La forma más explícita es usar match:



let result = read_file("config.txt");

match result { Ok(content) => println!("Archivo leído: {}", content), Err(e) => eprintln!("Error: {}", e),}


Esto es un análogo de try/catch, pero más flexible y controlable.



1.3. Métodos auxiliares



  • .unwrap() — entra en pánico ante un error (solo para prototipos).
  • .expect(msg) — entra en pánico con un mensaje personalizado.
  • .unwrap_or(default) — retorna un valor por defecto.
  • .is_ok() / .is_err() — verificación de estado.


2. Option<T>: trabajo seguro con ausencia de valor



Option es otro enum con las variantes Some(T) y None. Reemplaza a null y nullptr, eliminando errores de desreferenciación de puntero nulo.



2.1. Ejemplo de uso



fn find_user(id: u32) -> Option<String> {    if id == 1 {        Some("Alice".to_string())    } else {        None    }}

let user = find_user(2);println!("Usuario: {}", user.unwrap_or("Invitado".to_string()));


2.2. Combinación con Result



A menudo Option se convierte en Result para un manejo uniforme:



fn get_user_name(id: u32) -> Result<String, String> {    find_user(id).ok_or("Usuario no encontrado".to_string())}


El método .ok_or() convierte Some en Ok y None en Err.



3. Operador ?: elegante reemplazo de try/catch



El operador ? es azúcar sintáctico que desempaqueta automáticamente Result o Option. Solo está disponible en funciones que retornan el tipo correspondiente.



3.1. Ejemplo con cadena de llamadas



use std::num::ParseIntError;

fn parse_and_add(a: &str, b: &str) -> Result<i32, ParseIntError> { let x: i32 = a.parse()?; let y: i32 = b.parse()?; Ok(x

Blogs

Book Recommendations