Tipos de Erro Personalizados
Crates de biblioteca definem enums de erro que encapsulam falhas subjacentes, implementam std::error::Error, Display e From para uso ergonômico com ?.
Receita
use std::fmt;
#[derive(Debug)]
enum DataError {
Io(std::io::Error),
Parse(std::num::ParseIntError),
}
impl fmt::Display for DataError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DataError::Io(e) => write!(f, "io: {e}"),
DataError::Parse(e) => write!(f, "parse: {e}"),
}
}
}
impl std::error::Error for DataError {}
impl From<std::io::Error> for DataError {
fn from(e: std::io::Error) -> Self { DataError::Io(e) }
}Quando usar isso: Bibliotecas públicas que expõem tipos de erro estáveis nos quais os consumidores podem fazer match.
Exemplo de Trabalho
fn load_port(path: &str) -> Result<u16, DataError> {
let s = std::fs::read_to_string(path)?;
let p = s.trim().parse()?;
Ok(p)
}Com From para ParseIntError adicionado de forma semelhante.
O que isso demonstra:
- Um único enum agrega fontes de erro
?converte automaticamente- Chamadores podem usar
matchem variantes deDataError
Mergulho Profundo
Implemente source() em Error para encadear causas. Use #[non_exhaustive] em enums de erro públicos para semver.
Armadilhas
- Apenas erros de string - Difícil de comparar programaticamente. Correção: Variantes de enum tipadas.
Fromausente -?falha. Correção: derive ou implementeFrom.- Vazamento de erros internos - Quebra o semver se exposto. Correção: Mapeie para o enum público.
- Tipo de erro enorme - Custo de clonagem. Correção:
Arcpara a fonte ou erro interno emBox. - Não
Send/Sync- Quebra threads. Correção: Garanta que os erros encapsulados sejamSend + Sync.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
thiserror | Derivar boilerplate | Crates internos minúsculos |
anyhow | Flexibilidade da aplicação | API de biblioteca estável |
Box<dyn Error> | Binários rápidos | Necessidade de correspondência tipada |
FAQs
Objeto de trait de erro?
`BoxCadeia de `source()`?
Percorra `source()` para logging da causa raiz.non_exhaustive?
Enums públicos compatíveis com versões futuras.flatten thiserror?
O atributo `#[from]` gera `From`.Mapeamento HTTP?
Implemente `IntoResponse` na camada de aplicação, não na biblioteca.Erros serde?
Encapsule a variante `serde_json::Error`.Erro `no_std`?
Traits de erro `core` em ecossistemas `no_std`.Clonar erros?
Frequentemente encapsula `Arc` ou armazena mensagens estáticas.Comparar erros?
Evite - use `match` no enum de tipo em vez disso.Testes?
Afirme o tipo de erro via `downcast` ou `match`.Relacionados
Versões da Pilha: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4 e Polars 0.46+.