Skip to content

Add facility to appropriately handle JavaScript errors #14

Description

@camio

Information in JavaScript errors is currently being discarded as discussed here. This task is to instead panic when a JavaScript error is a precondition violation (e.g. when a TypeError is thrown) and otherwise propagate an anyhow::Result that embeds the information contained in the JavaScript error.

This work consists of three parts. The first is to create an error type, JsonEncodedError, that, when used as the error part of a Result, is compatible with anyhow.

#[derive(Debug)]
struct JsonEncodedError(serde_json::Value);

impl fmt::Display for JsonEncodedError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl std::error::Error for JsonEncodedError {}

The second part is to create an extension trait on Result<T, JsValue> with a method normalized that returns a Result<T,JsonEncodedError>. This function will panic if the parameter is an Err and encodes a JavaScript TypeError or some other exception that is always used to denote a precondition violation. If the parameter is an Err and doesn't indicate a precondition violation, a JsonEncodedError will be formed and returned using a technique like this:

let error_as_jsonencodederror = JsonEncodedError(
    serde_wasm_bindgen::from_value(error_as_jsvalue)
        .expect("JsValue to serde_json::Value conversion always succeeds"),
)

The final part is to update all relevant code to make use of this. For example,

let blob = Blob::new_with_str_sequence(&array)
    .map_err(|_| anyhow!("Failed to create Blob from content"))?;

becomes,

let blob = Blob::new_with_str_sequence(&array).normalized()?;

Note that we're not adding additional context here because it isn't adding anything useful to the stack trace that anyhow already provides. At a later date it might make sense to add a .context(…) method returning an anyhow, alongside .normalize().

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions