Совместимость типов ошибок
При определении собственного типа ошибки есть несколько распространённых соглашений, которым нужно следовать, чтобы быть совместимым с более широкой экосистемой:
- Реализуйте трейт
Errorиз стандартной библиотеки. - Получите
Debugчерез derive и реализуйтеDisplay(это требуется дляError). - Реализуйте преобразования
Fromдля базовых типов ошибок, чтобы поддержать автоматическое преобразование типов ошибок с помощью?.
// Copyright 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0
use std::error::Error;
use std::io::Read;
use std::{fmt, fs, io};
#[derive(Debug)]
enum ReadUsernameError {
IoError(io::Error),
EmptyUsername,
}
impl Error for ReadUsernameError {}
impl fmt::Display for ReadUsernameError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::IoError(e) => write!(f, "I/O error: {e}"),
Self::EmptyUsername => write!(f, "Username file was empty"),
}
}
}
impl From<io::Error> for ReadUsernameError {
fn from(err: io::Error) -> Self {
Self::IoError(err)
}
}
-
Любой тип можно использовать как тип ошибки для
Result: нет требований к трейтам, подходят и структуры, и перечисления, а когда ошибке не нужно нести никаких данных, можно даже использовать пустые типы нулевого размера, например(). -
Хотя строгих требований к типам ошибок нет, для совместимости с экосистемой есть несколько соглашений, которым стоит следовать.
-
Мы уже видели, как трейт
Fromможно использовать для автоматического преобразования типов ошибок с помощью оператора?. -
Стандартная библиотека предоставляет маркерный трейт
Error, чтобы показать, что тип представляет ошибку. -
Errorзависит отDebug(который можно получить через derive) иDisplay(который нужно реализовать вручную). Они гарантируют, что ошибку всегда можно превратить в строку для логирования или показа пользователю. -
Трейт
Errorсам по себе не предоставляет никакой функциональности, но в нескольких слайдах мы посмотрим, какErrorможно использовать для создания динамических типов ошибок. -
Эти реализации трейтов — часть шаблонного кода, который приходится писать для каждого собственного типа ошибки. На следующем слайде мы посмотрим на крейт из экосистемы, который помогает сократить этот шаблонный код.