godhar
godhar

Reputation: 1392

Unable to implement custom enum wrapper for std::error::Error

I am trying to figure out how the error enum works to wrap std::error:Error by passing in bad input for Url. I wish to wrap url::ParseError.

use std::error::Error;
use std::fmt::Display;

#[derive(Debug)]
pub enum WordCount {
    UrlError(url::ParseError),
}

impl Display for WordCount {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            WordCount::UrlError(e) => {
                write!(f, "{}", e)
            },
        }
    }
}

impl std::error::Error for WordCount {}

impl From<url::ParseError> for WordCount {
    fn from(err: url::ParseError) -> Self {
        WordCount::UrlError(err)
    }
} 

pub fn run() -> Result<String, WordCount> {
    let args: Vec<String> = env::args().collect();
    let arg = &args[1].as_ref();
    let domain = Url::parse(arg);

    match domain {
        Ok(_) => {}
        Err(err) => return Err(WordCount::UrlError(err)),
   };

    Ok("".to_owned())
}

If I replace the following line: Err(err) => return Err(WordCount::UrlError(err)), in the fn run()

with: panic!("some string") e.g

   match domain {
    Ok(domain) => println!("happy domain"),
    Err(err) => panic!("panicking"),
};

Then I can see an error print to the terminal. But not with the implementation, nothing prints to stderr even if I have implemented Display.

Upvotes: 0

Views: 875

Answers (1)

Netwave
Netwave

Reputation: 42716

Just returning an error doesn't implicetly print it. You could make your main function to return the same error, then your program will report the message at the end of execution. As an example:

use url::Url;
use std::error::Error;
use std::fmt::Display;

#[derive(Debug)]
pub enum CrawlerError {
    UrlError(url::ParseError),
}

impl Display for CrawlerError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            CrawlerError::UrlError(e) => {
                write!(f, "{}", e)
            },
        }
    }
}

impl std::error::Error for CrawlerError {}

impl From<url::ParseError> for CrawlerError {
    fn from(err: url::ParseError) -> Self {
        CrawlerError::UrlError(err)
    }
} 

pub fn run() -> Result<String, CrawlerError> {
    let domain = Url::parse("foo/bar");

    match domain {
        Ok(_) => Ok("".to_string()),
        Err(err) => Err(CrawlerError::UrlError(err)),
   }

}

fn main() -> Result<(), CrawlerError> {
    run()?;
    Ok(())
}

Playground

Results:

   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 1.25s
     Running `target/debug/playground`
Error: UrlError(RelativeUrlWithoutBase)

Upvotes: 1

Related Questions