-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Discovered in #12689, this test currently fails:
#[test]
#[cfg(feature = "anyhow")]
fn anyhow_source_loses_downcast() -> Result<()> {
let e: anyhow::Error = TestError(1).into();
assert!(e.downcast_ref::<TestError>().is_some());
let e: Error = Error::from_anyhow(e);
assert!(e.downcast_ref::<TestError>().is_some());
Ok(())
}Specifically the is, downcast, downcast_ref, and downcast_mut methods do not work on wasmtime::Error when the original source of the error is an anyhow::Error. This is due to the way the implementation is organized right now where the holder of anyhow::Error receives a TypeId, not a generic type parameter, menaing that we can't plumb this into anyhow's methods.
The fix for this is probably going to look like this where the existing methods, if they all fail, have a fall-through case which explicitly checks for anyhow::Error in the top-level methods with E type parameters. If the underlying error is anyhow::Error then we'd also delegate to anyhow's methods with the E type parameter.
This is all in lieu of raw/unsafe accessors being added to anyhow, which is probably something we don't want to pursue just yet. I'll also know that converting anyhow::Error to wasmtime::Error and then back to anyhow::Error will work correctly after #12689 insofar as downcasts of the final anyhow::Error will work as expected. That lessens the severity of this issue for now I think since embedders that are anyhow focused can work around this issue with that sort of conversion.