Трейт Error
Трейт Error является фундаментальным трейтом
для представления ошибок в Rust. Он определяет
базовый интерфейс, которому должны соответствовать
все типы ошибок. Трейт Error требует
реализации трейтов Debug и Display,
а также предоставляет методы для получения
исходной ошибки и преобразования в динамический тип.
Основные методы трейта Error:
source возвращает опциональную ссылку
на исходную ошибку, description
(устаревший) возвращает строковое описание,
cause (устаревший) возвращает причину ошибки,
provide используется для извлечения
дополнительной информации.
Синтаксис
pub trait Error: Debug + Display
{
fn source(&self) -> Option<&(dyn Error + 'static)>;
fn description(&self) -> &str;
fn cause(&self) -> Option<&dyn Error>;
fn provide<'a>(&'a self, request: &mut Request<'a>);
}
Пример
Давайте создадим пользовательский тип ошибки,
реализующий трейт Error:
use std::error::Error;
use std::fmt;
#[derive(Debug)]
struct MyError
{
message: String,
}
impl fmt::Display for MyError
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
{
write!(f, "{}", self.message)
}
}
impl Error for MyError {}
fn main()
{
let err = MyError { message: String::from("something went wrong") };
println!("{}", err);
}
Результат выполнения кода:
"something went wrong"
Пример
Давайте используем метод source для
получения исходной ошибки:
use std::error::Error;
use std::fmt;
#[derive(Debug)]
struct InnerError;
impl fmt::Display for InnerError
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
{
write!(f, "inner error")
}
}
impl Error for InnerError {}
#[derive(Debug)]
struct OuterError
{
inner: InnerError,
}
impl fmt::Display for OuterError
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
{
write!(f, "outer error")
}
}
impl Error for OuterError
{
fn source(&self) -> Option<&(dyn Error + 'static)>
{
Some(&self.inner)
}
}
fn main()
{
let err = OuterError { inner: InnerError };
if let Some(source) = err.source()
{
println!("Source: {}", source);
}
}
Результат выполнения кода:
"Source: inner error"
Пример
Давайте используем трейт Error
в качестве возвращаемого типа функции:
use std::error::Error;
use std::fmt;
#[derive(Debug)]
struct ParseError
{
message: String,
}
impl fmt::Display for ParseError
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
{
write!(f, "{}", self.message)
}
}
impl Error for ParseError {}
fn parse_number(s: &str) -> Result<i32, Box<dyn Error>>
{
let num = s.parse::<i32>().map_err(|_| {
Box::new(ParseError {
message: String::from("failed to parse number"),
}) as Box<dyn Error>
})?;
Ok(num)
}
fn main()
{
match parse_number("12345")
{
Ok(n) => println!("Parsed: {}", n),
Err(e) => println!("Error: {}", e),
}
match parse_number("abcde")
{
Ok(n) => println!("Parsed: {}", n),
Err(e) => println!("Error: {}", e),
}
}
Результат выполнения кода:
"Parsed: 12345"
"Error: failed to parse number"
Смотрите также
-
оператор
?,
который упрощает распространение ошибок -
макрос
panic!,
который вызывает панику с сообщением об ошибке -
метод
unwrap,
который извлекает значение или вызывает панику -
трейт
CustomError,
который позволяет создавать собственные типы ошибок