Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> It only works when your function returns error of the same type as expression inside 'try!' or '?' macros.

The language has actually thought of this case -- it turns out you can map lower-level errors into your higher-level error type by implementing the `From<E>` trait. E.g.:

    use std::io;
    pub enum MyErr { Io(io::Error), Custom(String) }

    impl From<io::Error> for MyErr {
        fn from(err: io::Error) -> MyErr { MyErr::Io(err) }
    }

    fn do_stuff() -> Result<(), MyErr> {
        let f = try!(File::open(...));
        // ...
    }


Or you can call map_err to do an on-the-spot transformation if you don't have a general way to go from Error A to Error B.

I still sometimes make mistakes reading rust code with the ? at the end of the line, but it's just a question of what type is it and does the line return. Both of which are handled by the compiler in the end, so you get a little bit of extra knowledge that even if you misread the line of code, there's often limits to how much damage you can cause.


The error-chain [0] crate helps to reduce this boilerplate. I usually don't like macro magic like this, but the code is so straightforward that you can trust the macro to work as expected.

[0]: https://github.com/brson/error-chain


Well, usual pattern matching will be even shorter, so I'm talking exactly about cases when lazyness provokes programmer just return that underlying type than write pattern matching or implement trait.


It would still be true with a simple error code. It's always easier to reuse an existing abstraction (in this case, existing set of codes) than it is to define a new one.


When you write function first time, you don't have set of codes yet. When you write second function, you already have underlying error in use :)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: