Hacker News new | ask | show | jobs
by ryandv 410 days ago
There are patterns to address it such as creating your own Result type alias with the error type parameter (E) fixed to an error type you own:

    type Result<T> = result::Result<T, MyError>;

    #[derive(Debug)]
    enum MyError {
        IOError(String)
        // ...
    }
Your owned (i.e. not third-party) Error type is a sum type of error types that might be thrown by other libraries, with a newtype wrapper (`IOError`) on top.

Then implement the `From` trait to map errors from third-party libraries to your own custom Error space:

    impl From<io::Error> for MyError {
        fn from(e: io::Error) -> MyError {
            MyError::IOError(e.to_string())
        }
    }
Now you can convert any result into a single type that you control by transforming the errors:

    return sender
        .write_all(msg.as_bytes())
        .map_err(|e| e.into());
There is a little boilerplate and mapping between error spaces that is required but I don't find it that onerous.
1 comments

I scratch my head when people try to justify Rust's implementation of X. It looks absolutely horrendous, IMO.

I would rather have what OCaml has: https://ocaml.org/docs/error-handling.