Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to manually return a Result<(), Box<dyn Error>>?

I want to return an error from a function in case a condition is true:

use std::error::Error;  pub fn run() -> Result<(), Box<dyn Error>> {     // -- snip ---      if condition {         // return error     }      // -- snip --      Ok(()) }  fn main() {} 

I probably don't have the basics of the typesystem down, but everywhere I looked people use the ? operator, so I can't figure out what type to return.

  1. Is it possible to just return an error like this?
  2. Is there a better way to handle this logic?
like image 691
rect0x51 Avatar asked Jul 27 '18 03:07

rect0x51


2 Answers

Error is a trait and you want to return a trait object (note the dyn keyword), so you need to implement this trait:

use std::error::Error; use std::fmt;  #[derive(Debug)] struct MyError(String);  impl fmt::Display for MyError {     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {         write!(f, "There is an error: {}", self.0)     } }  impl Error for MyError {}  pub fn run() -> Result<(), Box<dyn Error>> {     let condition = true;      if condition {         return Err(Box::new(MyError("Oops".into())));     }      Ok(()) }  fn main() {     if let Err(e) = run() {         println!("{}", e); // "There is an error: Oops"     } } 
  • Create your own error type,
  • Implement Debug, Display, then Error for it,
  • If there is an error, return the Err variant of Result.

I advise you to use failure that remove all the error boilerplate:

#[derive(Fail, Debug)] #[fail(display = "There is an error: {}.", _0)] struct MyError(String); 

--

Note that if you expect an Error, you can return whatever type you want, given that it implements Error. This includes the error types in std.

like image 132
Boiethios Avatar answered Oct 06 '22 08:10

Boiethios


I am new to Rust, but here is my dirty hack to return custom errors, given that the function is set to return Result<(), Box<dyn Error>>:

fn serve(config: &Config, stream: TcpStream) -> Result<(), Box<dyn Error>> {     // ...     if request_is_bad() {         // This returns immediately a custom "Bad request" error         Err("Bad request")?;     }     // ... } 
like image 41
jimis Avatar answered Oct 06 '22 06:10

jimis