CodeBlanks Logo Icon CodeBlanks

thiserror

thiserror crate'i ile derive edilen hata türleri oluşturursun.

thiserror

Kütüphanelerde hata türleri genellikle bir enum'dır ve her variant için Display yazmak tekrarlıdır. thiserror crate'i bunu derive ile üretir:

// Cargo.toml: thiserror = "1"
use thiserror::Error;

#[derive(Debug, Error)]
enum AyarHatasi {
    #[error("eksik anahtar: {0}")]
    Eksik(String),
    #[error("geçersiz değer: {anahtar}={deger}")]
    Gecersiz { anahtar: String, deger: String },
}

Ürettiği kod, elle yazacağın impl Display ve impl Error ile birebir aynıdır; çalışma anı maliyeti yoktur.

Elle yazılan karşılığı

Alıştırma ortamında dış crate olmadığı için aynı türü elle yazacağız. thiserror'ın arkasında olan budur:

impl fmt::Display for AyarHatasi {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            AyarHatasi::Eksik(a) => write!(f, "eksik anahtar: {a}"),
            AyarHatasi::Gecersiz { anahtar, deger } => {
                write!(f, "geçersiz değer: {anahtar}={deger}")
            }
        }
    }
}

impl std::error::Error for AyarHatasi {}

Uygulama Ayar hataları

AyarHatasi enum'ını Eksik(String) ve Gecersiz { anahtar, deger } variant'larıyla tanımla; Display ve Error'ı elle uygula. Eksik("port") ve Gecersiz { anahtar: "port", deger: "abc" } değerlerini ayrı satırlara {} ile yazdır.

Başlangıç kodu

main.rs
use std::fmt;

fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
use std::fmt;

#[derive(Debug)]
enum AyarHatasi {
    Eksik(String),
    Gecersiz { anahtar: String, deger: String },
}

impl fmt::Display for AyarHatasi {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            AyarHatasi::Eksik(a) => write!(f, "eksik anahtar: {a}"),
            AyarHatasi::Gecersiz { anahtar, deger } => {
                write!(f, "geçersiz değer: {anahtar}={deger}")
            }
        }
    }
}

impl std::error::Error for AyarHatasi {}

fn main() {
    let a = AyarHatasi::Eksik(String::from("port"));
    let b = AyarHatasi::Gecersiz {
        anahtar: String::from("port"),
        deger: String::from("abc"),
    };
    println!("{}", a);
    println!("{}", b);
}

Beklenen çıktı

eksik anahtar: port
geçersiz değer: port=abc

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 <code>thiserror</code> mı <code>anyhow</code> mı? Genel kural nedir?

  • Her yerde thiserror
  • İkisi aynı şeyi yapar
  • Kütüphanede thiserror (somut türler), uygulamada anyhow (tek esnek tür) Doğru cevap
  • Her yerde anyhow

Açıklama: Kütüphane kullanıcısı hatayı türüne göre ele almak ister; uygulama ise çoğunlukla hatayı raporlar.

2 Mesaj özniteliği

Soru
#[derive(Debug, Error)]
enum AyarHatasi {
    #[____("eksik anahtar: {0}")]
    Eksik(String),
}
Cevap
#[derive(Debug, Error)]
enum AyarHatasi {
    #[error("eksik anahtar: {0}")]
    Eksik(String),
}

Açıklama: thiserror her variant'ın mesajını #[error(..)] ile alır.

3 Değer ve mesajı

Kavram Anlamı
Eksik("port") eksik anahtar: port
Gecersiz { port, abc } geçersiz değer: port=abc
#[error("{0}")] İlk alan
#[error(transparent)] İçteki hatanın mesajı

Orta seviye bölümündeki tüm dersler