Error::source în Rust

Returnează eroarea care a cauzat eroarea curentă, dacă există, ca să poți afișa tot lanțul de cauze.

Sintaxă
fn source(&self) -> Option<&(dyn Error + 'static)>

Ce face Error::source

O eroare de nivel înalt („nu pot încărca setările”) are de multe ori o cauză de nivel jos („fișierul nu există”). source() returnează această cauză, ca Some(&eroare), sau None dacă nu există.

Implicit, source returnează None. Când eroarea ta împachetează altă eroare, suprascrie metoda și returnează Some(&self.cauza). Apelând source() în buclă, poți afișa tot lanțul.

Ce returnează

Option<&(dyn Error + 'static)>: cauza erorii sau None.

Exemple

Exemplul 1: O eroare care își păstrează cauza

EroareSetari împachetează eroarea de citire și o returnează din source. Bucla afișează tot lanțul.

use std::error::Error;
use std::fmt;
use std::fs;
use std::io;

#[derive(Debug)]
struct EroareSetari {
    cale: String,
    cauza: io::Error,
}

impl fmt::Display for EroareSetari {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "nu pot încărca setările din {}", self.cale)
    }
}

impl Error for EroareSetari {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        Some(&self.cauza)
    }
}

fn incarca(cale: &str) -> Result<String, EroareSetari> {
    fs::read_to_string(cale).map_err(|cauza| EroareSetari { cale: cale.to_string(), cauza })
}

fn main() {
    if let Err(e) = incarca("setari.toml") {
        println!("Eroare: {e}");
        let mut cauza = e.source();
        while let Some(c) = cauza {
            println!("  cauzată de: {c}");
            cauza = c.source();
        }
    }
}

Rezultat

Eroare: nu pot încărca setările din setari.toml
  cauzată de: No such file or directory (os error 2)

Exemplul 2: Erorile simple nu au cauză

use std::error::Error;

fn main() {
    let e = "abc".parse::<i32>().unwrap_err();
    println!("eroare: {e}");
    println!("are cauză: {}", e.source().is_some());
}

Rezultat

eroare: invalid digit found in string
are cauză: false

Greșeli frecvente

  • Repeți în Display și mesajul cauzei, apoi afișezi și lanțul de source: mesajul apare de două ori. Alege una dintre variante.
  • Folosești metoda veche cause(): este depreciată din Rust 1.33; folosește source().

Comenzi înrudite

  • Error: Trait-ul comun al tuturor tipurilor de eroare: o eroare se poate afișa (Display, Debug) și poate avea o cauză.
  • io::Error: Eroarea operațiilor de intrare/ieșire; kind() dă categoria (NotFound, PermissionDenied…), iar new() creează una proprie.
  • Result::map: map transformă valoarea din Ok și lasă eroarea neschimbată; map_err transformă eroarea și lasă valoarea neschimbată.