0Pricing
Learn Rust Coding · Урок

anyhow

Гибкая обработка ошибок приложения

«anyhow» — бесплатный урок Learn Rust Coding на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Learn Rust Coding, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Learn Rust Coding содержит 4 уроков всего.

Гибкие ошибки приложений

В коде приложения часто нужно просто передавать ошибки наверх вместе с контекстом, не определяя отдельное типизированное перечисление для каждой ошибки. Ящик anyhow предоставляет один удобный тип ошибки именно для этого.

Добавление anyhow

Добавьте его как зависимость. Он хорошо сочетается с thiserror: thiserror используют для библиотек, а anyhow — для исполняемых файлов.

[dependencies]
anyhow = "1.0"

Псевдоним anyhow::Result

anyhow::Result<T> — это сокращение для Result<T, anyhow::Error>. Тип Error может содержать любую ошибку, реализующую std::error::Error.

use anyhow::Result;

fn load() -> Result<String> {
    let text = std::fs::read_to_string("config.txt")?;
    Ok(text)
}

Автоматическое преобразование

Оператор ? автоматически преобразует любую стандартную ошибку в anyhow::Error, поэтому можно свободно смешивать типы ошибок.

use anyhow::Result;

fn parse_file(path: &str) -> Result<i32> {
    let text = std::fs::read_to_string(path)?; // io error
    let n: i32 = text.trim().parse()?;          // parse error
    Ok(n)
}

Добавление контекста

Метод .context() добавляет к ошибке понятное сообщение, формируя читаемую цепочку при сбое.

use anyhow::{Context, Result};

fn read_config(path: &str) -> Result<String> {
    let text = std::fs::read_to_string(path)
        .context("failed to read config file")?;
    Ok(text)
}

Отложенный контекст

Используйте with_context, если построение сообщения требует много ресурсов или данных во время выполнения; замыкание запускается только при ошибке.

use anyhow::{Context, Result};

fn open(path: &str) -> Result<String> {
    std::fs::read_to_string(path)
        .with_context(|| format!("could not open {path}"))
}

Создание ситуативных ошибок

Макрос anyhow! создаёт ошибку из сообщения, а bail! досрочно возвращает её.

use anyhow::{anyhow, bail, Result};

fn check(age: i32) -> Result<()> {
    if age < 0 {
        bail!("age cannot be negative");
    }
    if age > 150 {
        return Err(anyhow!("age {age} is implausible"));
    }
    Ok(())
}

Использование ensure!

ensure! похож на assert!, но возвращает ошибку вместо аварийного завершения.

use anyhow::{ensure, Result};

fn divide(a: i32, b: i32) -> Result<i32> {
    ensure!(b != 0, "division by zero");
    Ok(a / b)
}

anyhow в main

Возвращайте из main значение типа anyhow::Result<()>, чтобы при сбое получать красиво отформатированные цепочки ошибок.

use anyhow::Result;

fn main() -> Result<()> {
    let text = std::fs::read_to_string("data.txt")?;
    println!("{text}");
    Ok(())
}

Проверка причины

Хотя anyhow::Error непрозрачен, его всё равно можно исследовать. downcast_ref восстанавливает конкретный тип ошибки, когда нужно выбрать ветвь обработки.

use anyhow::Result;

fn report(err: anyhow::Error) {
    if let Some(io) = err.downcast_ref::<std::io::Error>() {
        println!("io error: {io}");
    } else {
        println!("other error: {err}");
    }
}

thiserror и anyhow

Практическое правило:

  • thiserror — библиотеки и типизированные ошибки, с которыми вызывающий код сопоставляется
  • anyhow — приложения, где ошибки просто передаются наверх вместе с контекстом

Ошибку thiserror можно беспрепятственно преобразовать в anyhow с помощью ?.

Быстрая проверка

Какой метод anyhow добавляет к ошибке описательное сообщение при её передаче наверх?

Итоги

Вы изучили ящик anyhow:

  • anyhow::Result<T> использует один гибкий тип ошибки
  • ? автоматически преобразует любую стандартную ошибку
  • .context() / with_context() добавляют понятные сообщения
  • anyhow!, bail! и ensure! создают ошибки
  • Лучше всего подходит для кода приложений (исполняемых файлов)

Часто задаваемые вопросы

Урок «anyhow» бесплатный?

Да — полный текст урока «anyhow» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Learn Rust Coding, подпишись на CoddyKit PRO. Курс Learn Rust Coding содержит 4 уроков всего.

Чему я научусь в уроке «anyhow»?

Гибкая обработка ошибок приложения Ты практикуешь Learn Rust Coding с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Learn Rust Coding?

Предыдущий опыт не требуется. Learn Rust Coding на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «anyhow»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Learn Rust Coding?

Да. Каждый урок Learn Rust Coding включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Result и оператор ?
  2. thiserror
  3. anyhow
  4. Преобразование ошибок
← Назад к Learn Rust Coding