Skip to content

Converting anyhow::Error to wasmtime::Error loses downcast information #12690

@alexcrichton

Description

@alexcrichton

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIncorrect behavior in the current implementation that needs fixing

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions