anyhow icon indicating copy to clipboard operation
anyhow copied to clipboard

Explicit constructor from Box<dyn Error + Send + Sync>

Open vorner opened this issue 5 years ago • 5 comments

Hello

I've noticed there's a (closed) issue about having a From<Box<dyn Error + Send + Sync>> impl, that refers to wanting that from std (#66)

But would it make sense to have an explicit constructor in the meantime? Eg. Error::from_box_error(..)? That way one would have to write some kind of map_error(Error::from_box_error)? instead of just ?, but that's probably better than nothing.

vorner avatar Apr 07 '20 14:04 vorner

anyhow! handles the conversion.

use anyhow::anyhow;

fn main() {
    let e: Box<dyn std::error::Error + Send + Sync> = unimplemented!();
    let e = anyhow!(e);
}

dtolnay avatar Apr 07 '20 19:04 dtolnay

Reading the docs, doesn't this stringify the error? Won't it lose all the source chain, type information and such?

I'd hope it could somehow convert the existing dyn Error from 2-words trait object to the internal 1-word trait object. Or is it not possible?

vorner avatar Apr 08 '20 11:04 vorner

Oh, I'm reading through the source code and it seems to be preserving it somehow. Would you mind if I send a PR making such usage clearer in the docs? Also, link from the Error type to the macro would make it little bit easier to find.

vorner avatar Apr 08 '20 11:04 vorner

Perhaps I'm missing something but anyhow! isn't very easy to use with ?.

fn main() -> anyhow::Result<()>{
   something_returning_boxed_error()?;
}

is a bit awkward - I mean:

fn main() -> anyhow::Result<()>{
  match something_returning_boxed_error(){
     Ok(v) => Ok(v),
     Err(e) => Err(anyhow!(e))
  }?
}

rbtcollins avatar Jul 01 '20 07:07 rbtcollins

It could be shorter with map_err instead of explicit match, eg something like:

something_returning_boxed_error().map_err(|e| anyhow!(e))?

This would be even slightly more ergonomic if it existed as a function/constructor/method, eg:

something_returning_boxed_error().map_err(Anyhow::from_boxed)?

But as long as Rust doesn't allow implementing impl From<Box<std::error::Error + Send + Sync>> for Anyhow, this is probably the best that can be done :-(.

vorner avatar Jul 02 '20 09:07 vorner

Looks like SNAFU crate handles this issue

https://stackoverflow.com/questions/65151237/why-doesnt-boxdyn-error-implement-error

The above fixes don't seem to work for where the Box<dyn Error> is not Send + Sync + 'static, just a plain box<dyn Error>

Ah, I can fix it my code for now.

DanielJoyce avatar Sep 30 '21 20:09 DanielJoyce