> Another way would be having more syntactic sugar for Result-style monadic error handling [...] Another issue raised by the original post is the fact that Rust has no top-level concrete error type that is convertible from all of the specific error types.
Well... Rust has both. Any type that satisfies the `Error` trait can be converted to `Box<Error>`, which is provided by the `impl<T: Error> Error for Box<T>` and `impl<E: Error> From<E> for Box<Error>` impls. And it so happens that this conversion can be done for you automatically using Rust's `?`. For example, this:
use std::error::Error;
use std::fs::File;
use std::io::{self, Read};
fn main() {
match example_explicit() {
Ok(data) => println!("{}", data),
Err(err) => println!("{}", err),
}
}
fn example_explicit() -> Result<String, Box<Error>> {
let file = match File::open("/foo/bar/baz") {
Ok(file) => file,
Err(err) => return Err(From::from(err)),
};
let mut rdr = io::BufReader::new(file);
let mut data = String::new();
if let Err(err) = rdr.read_to_string(&mut data) {
return Err(From::from(err));
}
Ok(data)
}
can be written as this without any fuss:
use std::error::Error;
use std::fs::File;
use std::io::{self, Read};
fn main() {
match example_sugar() {
Ok(data) => println!("{}", data),
Err(err) => println!("{}", err),
}
}
fn example_sugar() -> Result<String, Box<Error>> {
let file = File::open("/foo/bar/baz")?;
let mut rdr = io::BufReader::new(file);
let mut data = String::new();
rdr.read_to_string(&mut data)?;
Ok(data)
}
The problem is that the conversion to `Box<Error>` winds up making it harder for callers to inspect the underlying error if they want to. This is why this approach doesn't work well in libraries, but for simple CLI applications, it's Just Fine.
Well... Rust has both. Any type that satisfies the `Error` trait can be converted to `Box<Error>`, which is provided by the `impl<T: Error> Error for Box<T>` and `impl<E: Error> From<E> for Box<Error>` impls. And it so happens that this conversion can be done for you automatically using Rust's `?`. For example, this:
can be written as this without any fuss: The problem is that the conversion to `Box<Error>` winds up making it harder for callers to inspect the underlying error if they want to. This is why this approach doesn't work well in libraries, but for simple CLI applications, it's Just Fine.