failure icon indicating copy to clipboard operation
failure copied to clipboard

Recovering failures wrapped in io::Error could be easier

Open teythoon opened this issue 7 years ago • 0 comments

We have an object that implements io::Read, but needs to return failure::Errors during read operations. We therefore wrap failure::Errors into io::Error objects using failure::Compat. Now we (or our users) might want to recover the failure::Error (or rather failure::Fallible), and the way I came up with is a bit cumbersome:

    io::copy(&mut verifier, output)
        .map_err(|e| if e.get_ref().is_some() {
            // Wrapped failure::Error.  Recover it.
            failure::Error::from_boxed_compat(e.into_inner().unwrap())
        } else {
            // Plain io::Error.
            e.into()
        })?;

(If there is a more elegant way that I didn't find, please let me know!)

I thought it would be nice to have a convenience function for that, something along the lines of:

trait IoErrorExt {
    fn into_failure_error(self) -> failure::Error;
}

impl IoErrorExt for io::Error {
    fn into_failure_error(self) -> failure::Error {
        if self.get_ref().is_some() {
            // Wrapped failure::Error.  Recover it.
            failure::Error::from_boxed_compat(self.into_inner().unwrap())
        } else {
            // Plain io::Error.
            self.into()
        }
    }
}

trait IoResultExt<T> {
    fn into_fallible(self) -> failure::Fallible<T>;
}

impl<T> IoResultExt<T> for io::Result<T> {
    fn into_fallible(self) -> failure::Fallible<T> {
        self.map_err(|e| e.into_failure_error())
    }
}

With that I can write:

io::copy(&mut verifier, output).into_fallible()?;

It would be also possible to convert using From. Wdyt? I'd be happy to whip up a patch.

teythoon avatar Sep 12 '18 14:09 teythoon