actionbook/m06-trataamento-de-erros

CRÍTICO: Use para tratamento de erros. Gatilhos: Result, Option, Error, ?, unwrap, expect, panic, anyhow, thiserror, quando entrar em pânico vs retornar Result, erro personalizado, propagação de erros, tratamento de erros, uso de Result, quando usar panic

O que é m06-trataamento-de-erros?

Esta habilidade é essencial para o tratamento de erros em Rust, cobrindo desde padrões básicos como Result e Option até bibliotecas avançadas como anyhow e thiserror. Ela orienta o desenvolvedor sobre quando usar unwrap, expect e panic em comparação com a propagação de erros por meio do operador '?' ou retornando Result. A habilidade também aborda a criação de tipos de erro personalizados e a decisão entre pânico e resultados em diferentes contextos. Suportada por ferramentas como Claude Code e IDEs baseadas em IA, ela fornece uma referência completa para escrever código Rust robusto e idiomático, evitando crashes inesperados e garantindo que erros sejam tratados de forma adequada.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/actionbook/rust-skills/tree/main/skills/m06-error-handling

Installed? Explore more Programação e Desenvolvimento skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

actionbook/m06-tratamento-de-erros

CRÍTICO: Use para tratamento de erros. Gatilhos: Result, Option, Error, ?, unwrap, expect, panic, anyhow, thiserror, quando entrar em pânico vs retornar Result, erro personalizado, propagação de erros, tratamento de erros, uso de Result, quando usar panic

Visão Geral

Tratamento de erros é uma parte fundamental do desenvolvimento em Rust. Esta habilidade ajuda a decidir quando usar Result vs panic, como propagar erros com o operador ?, e como criar tipos de erro personalizados com as bibliotecas thiserror e anyhow.

Quando Usar Result vs panic

  • Result<T, E>: Use para erros recuperáveis que o chamador pode esperar e tratar (ex: arquivo não encontrado, falha de rede).
  • panic!: Use para erros irrecuperáveis ou bugs (ex: índice fora dos limites, invariante violada).

Propagação de Erros com ?

O operador ? simplifica a propagação de erros:

use std::fs::File;
use std::io::{self, Read};

fn ler_arquivo(caminho: &str) -> io::Result<String> {
    let mut arquivo = File::open(caminho)?;  // Propaga erro se falhar
    let mut conteudo = String::new();
    arquivo.read_to_string(&mut conteudo)?;
    Ok(conteudo)
}

Erros Personalizados com thiserror

thiserror é ótimo para bibliotecas onde você define tipos de erro específicos:

use thiserror::Error;

#[derive(Error, Debug)]
pub enum MeuErro {
    #[error("falha ao ler arquivo: {0}")]
    Io(#[from] std::io::Error),
    #[error("dados inválidos: {0}")]
    DadosInvalidos(String),
    #[error("recurso não encontrado")]
    NaoEncontrado,
}

Erros Dinâmicos com anyhow

anyhow é ideal para aplicativos que não se importam com o tipo exato do erro:

use anyhow::{Context, Result};

fn main() -> Result<()> {
    let dados = std::fs::read_to_string("config.toml")
        .context("falha ao ler arquivo de configuração")?;
    // ...
    Ok(())
}

unwrap e expect

Use unwrap e expect apenas quando você tem certeza de que o valor é Some/Ok, ou em protótipos/testes:

let valor = opcao.unwrap();  // Pânico se for `None`
let resultado = resultado.expect("mensagem personalizada");  // Pânico com mensagem

Boas Práticas

  1. Prefira Result em APIs públicas.
  2. Use panic! apenas para bugs ou invariantes.
  3. Documente os erros que sua função pode retornar.
  4. Use thiserror para bibliotecas e anyhow para aplicações.
  5. O operador ? é preferível a unwrap/expect na maioria dos casos.

Exemplo Completo

use anyhow::{Context, Result};
use thiserror::Error;

#[derive(Error, Debug)]
pub enum ErroProcessamento {
    #[error("dados vazios")]
    DadosVazios,
    #[error("falha na validação: {0}")]
    Validacao(String),
}

fn processar(dados: &str) -> Result<String, ErroProcessamento> {
    if dados.is_empty() {
        return Err(ErroProcessamento::DadosVazios);
    }
    // ...
    Ok(dados.to_uppercase())
}

fn main() -> Result<()> {
    let entrada = std::env::args().nth(1).context("argumento ausente")?;
    let saida = processar(&entrada)?;
    println!("{} ", saida);
    Ok(())
}

Palavras-chave

Result, Option, Error, ?, unwrap, expect, panic, anyhow, thiserror, erro personalizado, propagação, tratamento de erros

Individual skills in this repo

This repo contains 13 individual skills — each has its own dedicated page.

actionbook/m01-ownership

CRITICAL: Use for ownership/borrow/lifetime issues. Triggers: E0382, E0597, E0506, E0507, E0515, E0716, E0106, value moved, borrowed value does not live long enough, cannot move out of, use of moved value, ownership, borrow, lifetime, 'a, 'static, move, clone, Copy, 所有权, 借用, 生命周期

actionbook/m02-resource

CRITICAL: Use for smart pointers and resource management. Triggers: Box, Rc, Arc, Weak, RefCell, Cell, smart pointer, heap allocation, reference counting, RAII, Drop, should I use Box or Rc, when to use Arc vs Rc, 智能指针, 引用计数, 堆分配

actionbook/m03-mutability

CRITICAL: Use for mutability issues. Triggers: E0596, E0499, E0502, cannot borrow as mutable, already borrowed as immutable, mut, &mut, interior mutability, Cell, RefCell, Mutex, RwLock, 可变性, 内部可变性, 借用冲突

actionbook/m04-zero-cost

CRITICAL: Use for generics, traits, zero-cost abstraction. Triggers: E0277, E0308, E0599, generic, trait, impl, dyn, where, monomorphization, static dispatch, dynamic dispatch, impl Trait, trait bound not satisfied, 泛型, 特征, 零成本抽象, 单态化

actionbook/m05-type-driven

CRITICAL: Use for type-driven design. Triggers: type state, PhantomData, newtype, marker trait, builder pattern, make invalid states unrepresentable, compile-time validation, sealed trait, ZST, 类型状态, 新类型模式, 类型驱动设计

actionbook/m07-concurrency

CRITICAL: Use for concurrency/async. Triggers: E0277 Send Sync, cannot be sent between threads, thread, spawn, channel, mpsc, Mutex, RwLock, Atomic, async, await, Future, tokio, deadlock, race condition, 并发, 线程, 异步, 死锁

actionbook/m09-domain

CRITICAL: Use for domain modeling. Triggers: domain model, DDD, domain-driven design, entity, value object, aggregate, repository pattern, business rules, validation, invariant, 领域模型, 领域驱动设计, 业务规则

actionbook/m10-performance

CRITICAL: Use for performance optimization. Triggers: performance, optimization, benchmark, profiling, flamegraph, criterion, slow, fast, allocation, cache, SIMD, make it faster, 性能优化, 基准测试

actionbook/m11-ecosystem

Use when integrating crates or ecosystem questions. Keywords: E0425, E0433, E0603, crate, cargo, dependency, feature flag, workspace, which crate to use, using external C libraries, creating Python extensions, PyO3, wasm, WebAssembly, bindgen, cbindgen, napi-rs, cannot find, private, crate recommendation, best crate for, Cargo.toml, features, crate 推荐, 依赖管理, 特性标志, 工作空间, Python 绑定

actionbook/m12-lifecycle

Use when designing resource lifecycles. Keywords: RAII, Drop, resource lifecycle, connection pool, lazy initialization, connection pool design, resource cleanup patterns, cleanup, scope, OnceCell, Lazy, once_cell, OnceLock, transaction, session management, when is Drop called, cleanup on error, guard pattern, scope guard, 资源生命周期, 连接池, 惰性初始化, 资源清理, RAII 模式

actionbook/m13-domain-error

Use when designing domain error handling. Keywords: domain error, error categorization, recovery strategy, retry, fallback, domain error hierarchy, user-facing vs internal errors, error code design, circuit breaker, graceful degradation, resilience, error context, backoff, retry with backoff, error recovery, transient vs permanent error, 领域错误, 错误分类, 恢复策略, 重试, 熔断器, 优雅降级

actionbook/m14-mental-model

Use when learning Rust concepts. Keywords: mental model, how to think about ownership, understanding borrow checker, visualizing memory layout, analogy, misconception, explaining ownership, why does Rust, help me understand, confused about, learning Rust, explain like I'm, ELI5, intuition for, coming from Java, coming from Python, 心智模型, 如何理解所有权, 学习 Rust, Rust 入门, 为什么 Rust

actionbook/unsafe-checker

CRITICAL: Use for unsafe Rust code review and FFI. Triggers on: unsafe, raw pointer, FFI, extern, transmute, *mut, *const, union, #[repr(C)], libc, std::ffi, MaybeUninit, NonNull, SAFETY comment, soundness, undefined behavior, UB, safe wrapper, memory layout, bindgen, cbindgen, CString, CStr, 安全抽象, 裸指针, 外部函数接口, 内存布局, 不安全代码, FFI 绑定, 未定义行为

Habilidades Relacionadas