From 77d4c6f7e0ee9faf0ca73658a26da320d3754a2e Mon Sep 17 00:00:00 2001 From: Craig Bester Date: Fri, 6 Aug 2021 14:31:14 +0200 Subject: [PATCH] Improve Wasm error handling (#344) * Add WasmError Enables idiomatic Javascript error handling with js_sys::Error which includes error enum variant names. * Add WasmError test --- bindings/wasm/Cargo.toml | 1 + bindings/wasm/src/credential/credential.rs | 24 ++--- bindings/wasm/src/credential/presentation.rs | 14 +-- bindings/wasm/src/crypto/key_collection.rs | 10 +- bindings/wasm/src/crypto/key_pair.rs | 12 +-- bindings/wasm/src/error.rs | 91 +++++++++++++++++++ bindings/wasm/src/lib.rs | 4 +- bindings/wasm/src/message/authentication.rs | 10 +- .../wasm/src/message/credential_issuance.rs | 10 +- .../wasm/src/message/credential_options.rs | 10 +- .../wasm/src/message/credential_revocation.rs | 6 +- bindings/wasm/src/message/did_discovery.rs | 10 +- bindings/wasm/src/message/did_introduction.rs | 14 +-- bindings/wasm/src/message/did_resolution.rs | 10 +- .../wasm/src/message/features_discovery.rs | 10 +- .../src/message/presentation_verification.rs | 14 +-- bindings/wasm/src/message/timing.rs | 6 +- bindings/wasm/src/message/trust_ping.rs | 6 +- bindings/wasm/src/service.rs | 6 +- bindings/wasm/src/tangle/client.rs | 38 ++++---- bindings/wasm/src/tangle/config.rs | 12 +-- bindings/wasm/src/utils.rs | 12 --- bindings/wasm/src/wasm_did.rs | 10 +- bindings/wasm/src/wasm_document.rs | 84 ++++++++++------- bindings/wasm/src/wasm_verification_method.rs | 16 ++-- bindings/wasm/tests/wasm.rs | 10 ++ identity-account/Cargo.toml | 1 + identity-account/src/error.rs | 2 +- identity-comm/Cargo.toml | 1 + identity-comm/src/error.rs | 2 +- identity-core/Cargo.toml | 3 +- identity-core/src/error.rs | 2 +- identity-credential/Cargo.toml | 1 + identity-credential/src/error.rs | 2 +- identity-did/Cargo.toml | 1 + identity-did/src/error.rs | 2 +- identity-diff/Cargo.toml | 3 +- identity-diff/src/error.rs | 2 +- identity-iota/Cargo.toml | 1 + identity-iota/src/error.rs | 2 +- identity-iota/src/tangle/mod.rs | 4 + 41 files changed, 298 insertions(+), 181 deletions(-) create mode 100644 bindings/wasm/src/error.rs delete mode 100644 bindings/wasm/src/utils.rs diff --git a/bindings/wasm/Cargo.toml b/bindings/wasm/Cargo.toml index be0acbea70..c08ad4d6b0 100644 --- a/bindings/wasm/Cargo.toml +++ b/bindings/wasm/Cargo.toml @@ -18,6 +18,7 @@ console_error_panic_hook = { version = "0.1" } futures = { version = "0.3" } js-sys = { version = "0.3" } serde = { version = "1.0", features = ["derive"] } +serde_json = { version = "1.0", default-features = false } wasm-bindgen = { version = "0.2", features = ["serde-serialize"] } wasm-bindgen-futures = { version = "0.4", default-features = false } diff --git a/bindings/wasm/src/credential/credential.rs b/bindings/wasm/src/credential/credential.rs index 092f81c55d..810652e2cc 100644 --- a/bindings/wasm/src/credential/credential.rs +++ b/bindings/wasm/src/credential/credential.rs @@ -11,7 +11,7 @@ use identity::credential::CredentialBuilder; use identity::credential::Subject; use wasm_bindgen::prelude::*; -use crate::utils::err; +use crate::error::wasm_error; use crate::wasm_document::WasmDocument; #[wasm_bindgen(inspectable)] @@ -22,7 +22,7 @@ pub struct VerifiableCredential(pub(crate) Credential); impl VerifiableCredential { #[wasm_bindgen] pub fn extend(value: &JsValue) -> Result { - let mut base: Object = value.into_serde().map_err(err)?; + let mut base: Object = value.into_serde().map_err(wasm_error)?; if !base.contains_key("credentialSubject") { return Err("Missing property: `credentialSubject`".into()); @@ -35,23 +35,23 @@ impl VerifiableCredential { if !base.contains_key("@context") { base.insert( "@context".into(), - Credential::<()>::base_context().serde_into().map_err(err)?, + Credential::<()>::base_context().serde_into().map_err(wasm_error)?, ); } let mut types: Vec = match base.remove("type") { - Some(value) => value.serde_into().map(OneOrMany::into_vec).map_err(err)?, + Some(value) => value.serde_into().map(OneOrMany::into_vec).map_err(wasm_error)?, None => Vec::new(), }; types.insert(0, Credential::<()>::base_type().into()); - base.insert("type".into(), types.serde_into().map_err(err)?); + base.insert("type".into(), types.serde_into().map_err(wasm_error)?); if !base.contains_key("issuanceDate") { base.insert("issuanceDate".into(), Timestamp::now_utc().to_string().into()); } - base.serde_into().map_err(err).map(Self) + base.serde_into().map_err(wasm_error).map(Self) } #[wasm_bindgen] @@ -61,8 +61,8 @@ impl VerifiableCredential { credential_type: Option, credential_id: Option, ) -> Result { - let subjects: OneOrMany = subject_data.into_serde().map_err(err)?; - let issuer_url: Url = Url::parse(issuer_doc.0.id().as_str()).map_err(err)?; + let subjects: OneOrMany = subject_data.into_serde().map_err(wasm_error)?; + let issuer_url: Url = Url::parse(issuer_doc.0.id().as_str()).map_err(wasm_error)?; let mut builder: CredentialBuilder = CredentialBuilder::default().issuer(issuer_url); for subject in subjects.into_vec() { @@ -74,21 +74,21 @@ impl VerifiableCredential { } if let Some(credential_id) = credential_id { - builder = builder.id(Url::parse(credential_id).map_err(err)?); + builder = builder.id(Url::parse(credential_id).map_err(wasm_error)?); } - builder.build().map(Self).map_err(err) + builder.build().map(Self).map_err(wasm_error) } /// Serializes a `VerifiableCredential` object as a JSON object. #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } /// Deserializes a `VerifiableCredential` object from a JSON object. #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(json: &JsValue) -> Result { - json.into_serde().map_err(err).map(Self) + json.into_serde().map_err(wasm_error).map(Self) } } diff --git a/bindings/wasm/src/credential/presentation.rs b/bindings/wasm/src/credential/presentation.rs index 8659cba499..9256892d2f 100644 --- a/bindings/wasm/src/credential/presentation.rs +++ b/bindings/wasm/src/credential/presentation.rs @@ -8,7 +8,7 @@ use identity::credential::Presentation; use identity::credential::PresentationBuilder; use wasm_bindgen::prelude::*; -use crate::utils::err; +use crate::error::wasm_error; use crate::wasm_document::WasmDocument; #[wasm_bindgen(inspectable)] @@ -24,8 +24,8 @@ impl VerifiablePresentation { presentation_type: Option, presentation_id: Option, ) -> Result { - let credentials: OneOrMany = credential_data.into_serde().map_err(err)?; - let holder_url: Url = Url::parse(holder_doc.0.id().as_str()).map_err(err)?; + let credentials: OneOrMany = credential_data.into_serde().map_err(wasm_error)?; + let holder_url: Url = Url::parse(holder_doc.0.id().as_str()).map_err(wasm_error)?; let mut builder: PresentationBuilder = PresentationBuilder::default().holder(holder_url); @@ -38,21 +38,21 @@ impl VerifiablePresentation { } if let Some(presentation_id) = presentation_id { - builder = builder.id(Url::parse(presentation_id).map_err(err)?); + builder = builder.id(Url::parse(presentation_id).map_err(wasm_error)?); } - builder.build().map_err(err).map(Self) + builder.build().map_err(wasm_error).map(Self) } /// Serializes a `VerifiablePresentation` object as a JSON object. #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } /// Deserializes a `VerifiablePresentation` object from a JSON object. #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(json: &JsValue) -> Result { - json.into_serde().map_err(err).map(Self) + json.into_serde().map_err(wasm_error).map(Self) } } diff --git a/bindings/wasm/src/crypto/key_collection.rs b/bindings/wasm/src/crypto/key_collection.rs index ab44491348..ab675806ae 100644 --- a/bindings/wasm/src/crypto/key_collection.rs +++ b/bindings/wasm/src/crypto/key_collection.rs @@ -14,7 +14,7 @@ use wasm_bindgen::prelude::*; use crate::crypto::Digest; use crate::crypto::KeyPair; use crate::crypto::KeyType; -use crate::utils::err; +use crate::error::wasm_error; #[derive(Deserialize, Serialize)] struct JsonData { @@ -41,7 +41,7 @@ impl KeyCollection { /// Creates a new `KeyCollection` with the specified key type. #[wasm_bindgen(constructor)] pub fn new(type_: KeyType, count: usize) -> Result { - KeyCollection_::new(type_.into(), count).map_err(err).map(Self) + KeyCollection_::new(type_.into(), count).map_err(wasm_error).map(Self) } /// Returns the number of keys in the collection. @@ -123,13 +123,13 @@ impl KeyCollection { type_: self.0.type_().into(), }; - JsValue::from_serde(&data).map_err(err) + JsValue::from_serde(&data).map_err(wasm_error) } /// Deserializes a `KeyCollection` object from a JSON object. #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(json: &JsValue) -> Result { - let data: JsonData = json.into_serde().map_err(err)?; + let data: JsonData = json.into_serde().map_err(wasm_error)?; let iter: _ = data.keys.iter().flat_map(|data| { let pk: PublicKey = decode_b58(&data.public).ok()?.into(); @@ -139,7 +139,7 @@ impl KeyCollection { }); KeyCollection_::from_iterator(data.type_.into(), iter) - .map_err(err) + .map_err(wasm_error) .map(Self) } } diff --git a/bindings/wasm/src/crypto/key_pair.rs b/bindings/wasm/src/crypto/key_pair.rs index 0b986df27f..d28b78ee39 100644 --- a/bindings/wasm/src/crypto/key_pair.rs +++ b/bindings/wasm/src/crypto/key_pair.rs @@ -9,7 +9,7 @@ use identity::crypto::SecretKey; use wasm_bindgen::prelude::*; use crate::crypto::KeyType; -use crate::utils::err; +use crate::error::wasm_error; #[derive(Deserialize, Serialize)] struct JsonData { @@ -31,14 +31,14 @@ impl KeyPair { /// Generates a new `KeyPair` object. #[wasm_bindgen(constructor)] pub fn new(type_: KeyType) -> Result { - KeyPair_::new(type_.into()).map_err(err).map(Self) + KeyPair_::new(type_.into()).map_err(wasm_error).map(Self) } /// Parses a `KeyPair` object from base58-encoded public/secret keys. #[wasm_bindgen(js_name = fromBase58)] pub fn from_base58(type_: KeyType, public_key: &str, secret_key: &str) -> Result { - let public: PublicKey = decode_b58(public_key).map_err(err)?.into(); - let secret: SecretKey = decode_b58(secret_key).map_err(err)?.into(); + let public: PublicKey = decode_b58(public_key).map_err(wasm_error)?.into(); + let secret: SecretKey = decode_b58(secret_key).map_err(wasm_error)?.into(); Ok(Self((type_.into(), public, secret).into())) } @@ -64,13 +64,13 @@ impl KeyPair { secret: self.secret(), }; - JsValue::from_serde(&data).map_err(err) + JsValue::from_serde(&data).map_err(wasm_error) } /// Deserializes a `KeyPair` object from a JSON object. #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(json: &JsValue) -> Result { - let data: JsonData = json.into_serde().map_err(err)?; + let data: JsonData = json.into_serde().map_err(wasm_error)?; Self::from_base58(data.type_, &data.public, &data.secret) } diff --git a/bindings/wasm/src/error.rs b/bindings/wasm/src/error.rs new file mode 100644 index 0000000000..df0cfc0f66 --- /dev/null +++ b/bindings/wasm/src/error.rs @@ -0,0 +1,91 @@ +// Copyright 2020-2021 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +use std::borrow::Cow; + +use wasm_bindgen::JsValue; + +/// Convert an error into an idiomatic [js_sys::Error]. +pub fn wasm_error<'a, T>(error: T) -> JsValue +where + T: Into>, +{ + let wasm_err: WasmError = error.into(); + JsValue::from(wasm_err) +} + +/// Convenience struct to convert internal errors to [js_sys::Error]. Uses [std::borrow::Cow] +/// internally to avoid unnecessary clones. +/// +/// This is a workaround for orphan rules so we can implement [core::convert::From] on errors from +/// dependencies. +#[derive(Debug, Clone)] +pub struct WasmError<'a> { + pub name: Cow<'a, str>, + pub message: Cow<'a, str>, +} + +impl<'a> WasmError<'a> { + pub fn new(name: Cow<'a, str>, message: Cow<'a, str>) -> Self { + Self { name, message } + } +} + +/// Convert [WasmError] into [js_sys::Error] for idiomatic error handling. +impl From> for js_sys::Error { + fn from(error: WasmError<'_>) -> Self { + let js_error = js_sys::Error::new(&error.message); + js_error.set_name(&error.name); + js_error + } +} + +/// Convert [WasmError] into [wasm_bindgen::JsValue]. +impl From> for JsValue { + fn from(error: WasmError<'_>) -> Self { + JsValue::from(js_sys::Error::from(error)) + } +} + +/// Implement WasmError for each type individually rather than a trait due to Rust's orphan rules. +/// Each type must implement `Into<&'static str> + Display`. The `Into<&'static str>` trait can be +/// derived using `strum::IntoStaticStr`. +#[macro_export] +macro_rules! impl_wasm_error_from { + ( $($t:ty),* ) => { + $(impl From<$t> for WasmError<'_> { + fn from(error: $t) -> Self { + Self { + message: Cow::Owned(error.to_string()), + name: Cow::Borrowed(error.into()), + } + } + })* + } +} + +impl_wasm_error_from!( + identity::comm::Error, + identity::core::Error, + identity::credential::Error, + identity::did::Error, + identity::iota::Error +); + +impl From for WasmError<'_> { + fn from(error: serde_json::Error) -> Self { + Self { + name: Cow::Borrowed("serde_json::Error"), // the exact error code is embedded in the message + message: Cow::Owned(error.to_string()), + } + } +} + +impl From for WasmError<'_> { + fn from(error: identity::iota::BeeMessageError) -> Self { + Self { + name: Cow::Borrowed("bee_message::Error"), + message: Cow::Owned(error.to_string()), + } + } +} diff --git a/bindings/wasm/src/lib.rs b/bindings/wasm/src/lib.rs index 83935c74e9..8b153a3864 100644 --- a/bindings/wasm/src/lib.rs +++ b/bindings/wasm/src/lib.rs @@ -10,7 +10,9 @@ use wasm_bindgen::prelude::*; #[macro_use] mod macros; -mod utils; + +#[macro_use] +pub mod error; pub mod credential; pub mod crypto; diff --git a/bindings/wasm/src/message/authentication.rs b/bindings/wasm/src/message/authentication.rs index 94614571ef..7b0cb11339 100644 --- a/bindings/wasm/src/message/authentication.rs +++ b/bindings/wasm/src/message/authentication.rs @@ -4,7 +4,7 @@ use identity::comm; use wasm_bindgen::prelude::*; -use crate::utils::err; +use crate::error::wasm_error; #[wasm_bindgen(inspectable)] #[derive(Clone, Debug, PartialEq)] @@ -14,12 +14,12 @@ pub struct AuthenticationRequest(pub(crate) comm::AuthenticationRequest); impl AuthenticationRequest { #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } @@ -31,11 +31,11 @@ pub struct AuthenticationResponse(pub(crate) comm::AuthenticationResponse); impl AuthenticationResponse { #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } diff --git a/bindings/wasm/src/message/credential_issuance.rs b/bindings/wasm/src/message/credential_issuance.rs index a150c9c91d..e4acb1a324 100644 --- a/bindings/wasm/src/message/credential_issuance.rs +++ b/bindings/wasm/src/message/credential_issuance.rs @@ -4,7 +4,7 @@ use identity::comm; use wasm_bindgen::prelude::*; -use crate::utils::err; +use crate::error::wasm_error; #[wasm_bindgen(inspectable)] #[derive(Clone, Debug, PartialEq)] @@ -14,12 +14,12 @@ pub struct CredentialSelection(pub(crate) comm::CredentialSelection); impl CredentialSelection { #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } @@ -31,11 +31,11 @@ pub struct CredentialIssuance(pub(crate) comm::CredentialIssuance); impl CredentialIssuance { #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } diff --git a/bindings/wasm/src/message/credential_options.rs b/bindings/wasm/src/message/credential_options.rs index d5021d34e3..46ce617715 100644 --- a/bindings/wasm/src/message/credential_options.rs +++ b/bindings/wasm/src/message/credential_options.rs @@ -4,7 +4,7 @@ use identity::comm; use wasm_bindgen::prelude::*; -use crate::utils::err; +use crate::error::wasm_error; #[wasm_bindgen(inspectable)] #[derive(Clone, Debug, PartialEq)] @@ -14,12 +14,12 @@ pub struct CredentialOptionRequest(pub(crate) comm::CredentialOptionRequest); impl CredentialOptionRequest { #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } @@ -31,11 +31,11 @@ pub struct CredentialOptionResponse(pub(crate) comm::CredentialOptionResponse); impl CredentialOptionResponse { #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } diff --git a/bindings/wasm/src/message/credential_revocation.rs b/bindings/wasm/src/message/credential_revocation.rs index 295a781cd3..b1a80a80b1 100644 --- a/bindings/wasm/src/message/credential_revocation.rs +++ b/bindings/wasm/src/message/credential_revocation.rs @@ -4,7 +4,7 @@ use identity::comm; use wasm_bindgen::prelude::*; -use crate::utils::err; +use crate::error::wasm_error; #[wasm_bindgen(inspectable)] #[derive(Clone, Debug, PartialEq)] @@ -14,11 +14,11 @@ pub struct CredentialRevocation(pub(crate) comm::CredentialRevocation); impl CredentialRevocation { #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } diff --git a/bindings/wasm/src/message/did_discovery.rs b/bindings/wasm/src/message/did_discovery.rs index 78e7cc6b14..eedd0b3be1 100644 --- a/bindings/wasm/src/message/did_discovery.rs +++ b/bindings/wasm/src/message/did_discovery.rs @@ -4,7 +4,7 @@ use identity::comm; use wasm_bindgen::prelude::*; -use crate::utils::err; +use crate::error::wasm_error; #[wasm_bindgen(inspectable)] #[derive(Clone, Debug, PartialEq)] @@ -14,12 +14,12 @@ pub struct DidRequest(pub(crate) comm::DidRequest); impl DidRequest { #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } @@ -31,11 +31,11 @@ pub struct DidResponse(pub(crate) comm::DidResponse); impl DidResponse { #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } diff --git a/bindings/wasm/src/message/did_introduction.rs b/bindings/wasm/src/message/did_introduction.rs index fcdfdbe7a8..4809910d1e 100644 --- a/bindings/wasm/src/message/did_introduction.rs +++ b/bindings/wasm/src/message/did_introduction.rs @@ -4,7 +4,7 @@ use identity::comm; use wasm_bindgen::prelude::*; -use crate::utils::err; +use crate::error::wasm_error; #[wasm_bindgen(inspectable)] #[derive(Clone, Debug, PartialEq)] @@ -14,12 +14,12 @@ pub struct IntroductionProposal(pub(crate) comm::IntroductionProposal); impl IntroductionProposal { #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } @@ -31,12 +31,12 @@ pub struct IntroductionResponse(pub(crate) comm::IntroductionResponse); impl IntroductionResponse { #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } @@ -48,11 +48,11 @@ pub struct Introduction(pub(crate) comm::Introduction); impl Introduction { #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } diff --git a/bindings/wasm/src/message/did_resolution.rs b/bindings/wasm/src/message/did_resolution.rs index 63f6c2d5cb..10ba23c05f 100644 --- a/bindings/wasm/src/message/did_resolution.rs +++ b/bindings/wasm/src/message/did_resolution.rs @@ -4,7 +4,7 @@ use identity::comm; use wasm_bindgen::prelude::*; -use crate::utils::err; +use crate::error::wasm_error; #[wasm_bindgen(inspectable)] #[derive(Clone, Debug, PartialEq)] @@ -14,12 +14,12 @@ pub struct ResolutionRequest(pub(crate) comm::ResolutionRequest); impl ResolutionRequest { #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } @@ -31,11 +31,11 @@ pub struct ResolutionResponse(pub(crate) comm::ResolutionResponse); impl ResolutionResponse { #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } diff --git a/bindings/wasm/src/message/features_discovery.rs b/bindings/wasm/src/message/features_discovery.rs index 09707f7b94..31b5046725 100644 --- a/bindings/wasm/src/message/features_discovery.rs +++ b/bindings/wasm/src/message/features_discovery.rs @@ -4,7 +4,7 @@ use identity::comm; use wasm_bindgen::prelude::*; -use crate::utils::err; +use crate::error::wasm_error; #[wasm_bindgen(inspectable)] #[derive(Clone, Debug, PartialEq)] @@ -14,12 +14,12 @@ pub struct FeaturesRequest(pub(crate) comm::FeaturesRequest); impl FeaturesRequest { #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } @@ -31,11 +31,11 @@ pub struct FeaturesResponse(pub(crate) comm::FeaturesResponse); impl FeaturesResponse { #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } diff --git a/bindings/wasm/src/message/presentation_verification.rs b/bindings/wasm/src/message/presentation_verification.rs index 8b4c4280e2..387a05b6f0 100644 --- a/bindings/wasm/src/message/presentation_verification.rs +++ b/bindings/wasm/src/message/presentation_verification.rs @@ -4,7 +4,7 @@ use identity::comm; use wasm_bindgen::prelude::*; -use crate::utils::err; +use crate::error::wasm_error; #[wasm_bindgen(inspectable)] #[derive(Clone, Debug, PartialEq)] @@ -14,12 +14,12 @@ pub struct PresentationRequest(pub(crate) comm::PresentationRequest); impl PresentationRequest { #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } @@ -31,12 +31,12 @@ pub struct PresentationResponse(pub(crate) comm::PresentationResponse); impl PresentationResponse { #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } @@ -48,11 +48,11 @@ pub struct TrustedIssuer(pub(crate) comm::TrustedIssuer); impl TrustedIssuer { #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } diff --git a/bindings/wasm/src/message/timing.rs b/bindings/wasm/src/message/timing.rs index 5f50ab84b4..a9b9289fc7 100644 --- a/bindings/wasm/src/message/timing.rs +++ b/bindings/wasm/src/message/timing.rs @@ -5,7 +5,7 @@ use identity::comm; use identity::core::Timestamp; use wasm_bindgen::prelude::*; -use crate::utils::err; +use crate::error::wasm_error; #[wasm_bindgen(inspectable)] #[derive(Clone, Debug, PartialEq)] @@ -75,11 +75,11 @@ impl Timing { #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } diff --git a/bindings/wasm/src/message/trust_ping.rs b/bindings/wasm/src/message/trust_ping.rs index f5973d6e26..c9bb40e598 100644 --- a/bindings/wasm/src/message/trust_ping.rs +++ b/bindings/wasm/src/message/trust_ping.rs @@ -4,7 +4,7 @@ use identity::comm; use wasm_bindgen::prelude::*; -use crate::utils::err; +use crate::error::wasm_error; #[wasm_bindgen(inspectable)] #[derive(Clone, Debug, PartialEq)] @@ -14,11 +14,11 @@ pub struct TrustPing(pub(crate) comm::TrustPing); impl TrustPing { #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } diff --git a/bindings/wasm/src/service.rs b/bindings/wasm/src/service.rs index ef4f3dd014..c8b68b5ed9 100644 --- a/bindings/wasm/src/service.rs +++ b/bindings/wasm/src/service.rs @@ -1,7 +1,7 @@ // Copyright 2020-2021 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use crate::utils::err; +use crate::error::wasm_error; use identity::did::Service as IotaService; use wasm_bindgen::prelude::*; @@ -14,12 +14,12 @@ impl Service { /// Serializes a `Service` object as a JSON object. #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } /// Deserializes a `Service` object from a JSON object. #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } diff --git a/bindings/wasm/src/tangle/client.rs b/bindings/wasm/src/tangle/client.rs index 21f9cc9a35..753c45f8d8 100644 --- a/bindings/wasm/src/tangle/client.rs +++ b/bindings/wasm/src/tangle/client.rs @@ -19,9 +19,9 @@ use std::rc::Rc; use wasm_bindgen::prelude::*; use wasm_bindgen_futures::future_to_promise; +use crate::error::wasm_error; use crate::tangle::Config; use crate::tangle::WasmNetwork; -use crate::utils::err; #[wasm_bindgen] #[derive(Debug)] @@ -47,7 +47,7 @@ impl Client { #[wasm_bindgen(js_name = fromConfig)] pub fn from_config(config: &mut Config) -> Result { let future = config.take_builder()?.build(); - let output = executor::block_on(future).map_err(err); + let output = executor::block_on(future).map_err(wasm_error); output.map(Self::from_client) } @@ -56,7 +56,7 @@ impl Client { #[wasm_bindgen(js_name = fromNetwork)] pub fn from_network(network: WasmNetwork) -> Result { let future = IotaClient::from_network(network.into()); - let output = executor::block_on(future).map_err(err); + let output = executor::block_on(future).map_err(wasm_error); output.map(Self::from_client) } @@ -70,15 +70,15 @@ impl Client { /// Publishes an `IotaDocument` to the Tangle. #[wasm_bindgen(js_name = publishDocument)] pub fn publish_document(&self, document: &JsValue) -> Result { - let document: IotaDocument = document.into_serde().map_err(err)?; + let document: IotaDocument = document.into_serde().map_err(wasm_error)?; let client: Rc = self.client.clone(); let promise: Promise = future_to_promise(async move { client .publish_document(&document) .await - .map_err(err) - .and_then(|receipt| JsValue::from_serde(&receipt).map_err(err)) + .map_err(wasm_error) + .and_then(|receipt| JsValue::from_serde(&receipt).map_err(wasm_error)) }); Ok(promise) @@ -87,16 +87,16 @@ impl Client { /// Publishes a `DocumentDiff` to the Tangle. #[wasm_bindgen(js_name = publishDiff)] pub fn publish_diff(&self, message_id: &str, value: &JsValue) -> Result { - let diff: DocumentDiff = value.into_serde().map_err(err)?; - let message: MessageId = MessageId::from_str(message_id).map_err(err)?; + let diff: DocumentDiff = value.into_serde().map_err(wasm_error)?; + let message: MessageId = MessageId::from_str(message_id).map_err(wasm_error)?; let client: Rc = self.client.clone(); let promise: Promise = future_to_promise(async move { client .publish_diff(&message, &diff) .await - .map_err(err) - .and_then(|receipt| JsValue::from_serde(&receipt).map_err(err)) + .map_err(wasm_error) + .and_then(|receipt| JsValue::from_serde(&receipt).map_err(wasm_error)) }); Ok(promise) @@ -112,16 +112,16 @@ impl Client { } let client: Rc = self.client.clone(); - let did: IotaDID = did.parse().map_err(err)?; + let did: IotaDID = did.parse().map_err(wasm_error)?; let promise: Promise = future_to_promise(async move { - client.resolve(&did).await.map_err(err).and_then(|document| { + client.resolve(&did).await.map_err(wasm_error).and_then(|document| { let wrapper = DocWrapper { document: &document, message_id: document.message_id(), }; - JsValue::from_serde(&wrapper).map_err(err) + JsValue::from_serde(&wrapper).map_err(wasm_error) }) }); @@ -132,14 +132,14 @@ impl Client { #[wasm_bindgen(js_name = checkCredential)] pub fn check_credential(&self, data: &str) -> Result { let client: Rc = self.client.clone(); - let data: Credential = Credential::from_json(&data).map_err(err)?; + let data: Credential = Credential::from_json(&data).map_err(wasm_error)?; let promise: Promise = future_to_promise(async move { CredentialValidator::new(&*client) .validate_credential(data) .await - .map_err(err) - .and_then(|output| JsValue::from_serde(&output).map_err(err)) + .map_err(wasm_error) + .and_then(|output| JsValue::from_serde(&output).map_err(wasm_error)) }); Ok(promise) @@ -149,14 +149,14 @@ impl Client { #[wasm_bindgen(js_name = checkPresentation)] pub fn check_presentation(&self, data: &str) -> Result { let client: Rc = self.client.clone(); - let data: Presentation = Presentation::from_json(&data).map_err(err)?; + let data: Presentation = Presentation::from_json(&data).map_err(wasm_error)?; let promise: Promise = future_to_promise(async move { CredentialValidator::new(&*client) .validate_presentation(data) .await - .map_err(err) - .and_then(|output| JsValue::from_serde(&output).map_err(err)) + .map_err(wasm_error) + .and_then(|output| JsValue::from_serde(&output).map_err(wasm_error)) }); Ok(promise) diff --git a/bindings/wasm/src/tangle/config.rs b/bindings/wasm/src/tangle/config.rs index 55f6021f64..b6a5561bfd 100644 --- a/bindings/wasm/src/tangle/config.rs +++ b/bindings/wasm/src/tangle/config.rs @@ -5,8 +5,8 @@ use identity::iota::ClientBuilder; use std::time::Duration; use wasm_bindgen::prelude::*; +use crate::error::wasm_error; use crate::tangle::WasmNetwork; -use crate::utils::err; fn to_duration(seconds: u32) -> Duration { Duration::from_secs(u64::from(seconds)) @@ -45,7 +45,7 @@ impl Config { #[wasm_bindgen(js_name = setNode)] pub fn set_node(&mut self, url: &str) -> Result<(), JsValue> { - self.try_with_mut(|builder| builder.node(url).map_err(err)) + self.try_with_mut(|builder| builder.node(url).map_err(wasm_error)) } #[wasm_bindgen(js_name = setPrimaryNode)] @@ -59,7 +59,7 @@ impl Config { self.try_with_mut(|builder| { builder .primary_node(url, jwt.clone(), to_basic_auth(&username, &password)) - .map_err(err) + .map_err(wasm_error) }) } @@ -74,7 +74,7 @@ impl Config { self.try_with_mut(|builder| { builder .primary_pow_node(url, jwt.clone(), to_basic_auth(&username, &password)) - .map_err(err) + .map_err(wasm_error) }) } @@ -89,7 +89,7 @@ impl Config { self.try_with_mut(|builder| { builder .permanode(url, jwt.clone(), to_basic_auth(&username, &password)) - .map_err(err) + .map_err(wasm_error) }) } @@ -104,7 +104,7 @@ impl Config { self.try_with_mut(|builder| { builder .node_auth(url, jwt.clone(), to_basic_auth(&username, &password)) - .map_err(err) + .map_err(wasm_error) }) } diff --git a/bindings/wasm/src/utils.rs b/bindings/wasm/src/utils.rs deleted file mode 100644 index adcc9f6ecd..0000000000 --- a/bindings/wasm/src/utils.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2020-2021 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -use wasm_bindgen::JsValue; - -/// Convert errors so they are readable in JS -pub fn err(error: T) -> JsValue -where - T: ToString, -{ - error.to_string().into() -} diff --git a/bindings/wasm/src/wasm_did.rs b/bindings/wasm/src/wasm_did.rs index b27011c135..46a3ad91cc 100644 --- a/bindings/wasm/src/wasm_did.rs +++ b/bindings/wasm/src/wasm_did.rs @@ -6,8 +6,8 @@ use identity::iota::IotaDID; use wasm_bindgen::prelude::*; use crate::crypto::KeyPair; +use crate::error::wasm_error; use crate::tangle::WasmNetwork; -use crate::utils::err; /// @typicalname did #[wasm_bindgen(js_name = DID, inspectable)] @@ -22,22 +22,22 @@ impl WasmDID { let public: &[u8] = key.0.public().as_ref(); let network: Option<&str> = network.as_deref(); - IotaDID::from_components(public, network).map_err(err).map(Self) + IotaDID::from_components(public, network).map_err(wasm_error).map(Self) } /// Creates a new `DID` from a base58-encoded public key. #[wasm_bindgen(js_name = fromBase58)] pub fn from_base58(key: &str, network: Option) -> Result { - let public: Vec = decode_b58(key).map_err(err)?; + let public: Vec = decode_b58(key).map_err(wasm_error)?; let network: Option<&str> = network.as_deref(); - IotaDID::from_components(&public, network).map_err(err).map(Self) + IotaDID::from_components(&public, network).map_err(wasm_error).map(Self) } /// Parses a `DID` from the input string. #[wasm_bindgen] pub fn parse(input: &str) -> Result { - IotaDID::parse(input).map_err(err).map(Self) + IotaDID::parse(input).map_err(wasm_error).map(Self) } /// Returns the IOTA tangle network of the `DID`. diff --git a/bindings/wasm/src/wasm_document.rs b/bindings/wasm/src/wasm_document.rs index a8accc42f9..b7b2ba065d 100644 --- a/bindings/wasm/src/wasm_document.rs +++ b/bindings/wasm/src/wasm_document.rs @@ -24,8 +24,8 @@ use crate::credential::VerifiableCredential; use crate::credential::VerifiablePresentation; use crate::crypto::KeyPair; use crate::crypto::KeyType; +use crate::error::wasm_error; use crate::service::Service; -use crate::utils::err; use crate::wasm_did::WasmDID; use crate::wasm_verification_method::WasmVerificationMethod; @@ -65,14 +65,14 @@ impl WasmDocument { let public: &PublicKey = keypair.0.public(); let did: IotaDID = if let Some(network) = network.as_deref() { - IotaDID::with_network(public.as_ref(), network).map_err(err)? + IotaDID::with_network(public.as_ref(), network).map_err(wasm_error)? } else { - IotaDID::new(public.as_ref()).map_err(err)? + IotaDID::new(public.as_ref()).map_err(wasm_error)? }; let method: IotaVerificationMethod = - IotaVerificationMethod::from_did(did, &keypair.0, tag.as_deref()).map_err(err)?; - let document: IotaDocument = IotaDocument::from_authentication(method).map_err(err)?; + IotaVerificationMethod::from_did(did, &keypair.0, tag.as_deref()).map_err(wasm_error)?; + let document: IotaDocument = IotaDocument::from_authentication(method).map_err(wasm_error)?; Ok(NewDocument { key: keypair, @@ -89,14 +89,14 @@ impl WasmDocument { Some(net) => IotaDocument::from_keypair_with_network(&key.0, &net), None => IotaDocument::from_keypair(&key.0), }; - doc.map_err(err).map(Self) + doc.map_err(wasm_error).map(Self) } /// Creates a new DID Document from the given verification [`method`][`Method`]. #[wasm_bindgen(js_name = fromAuthentication)] pub fn from_authentication(method: &WasmVerificationMethod) -> Result { IotaDocument::from_authentication(method.0.clone()) - .map_err(err) + .map_err(wasm_error) .map(Self) } @@ -114,7 +114,7 @@ impl WasmDocument { #[wasm_bindgen(getter)] pub fn proof(&self) -> Result { match self.0.proof() { - Some(proof) => JsValue::from_serde(proof).map_err(err), + Some(proof) => JsValue::from_serde(proof).map_err(wasm_error), None => Ok(JsValue::NULL), } } @@ -126,7 +126,7 @@ impl WasmDocument { #[wasm_bindgen(setter = previousMessageId)] pub fn set_previous_message_id(&mut self, value: &str) -> Result<(), JsValue> { - let message: MessageId = MessageId::from_str(value).map_err(err)?; + let message: MessageId = MessageId::from_str(value).map_err(wasm_error)?; self.0.set_previous_message_id(message); @@ -139,14 +139,14 @@ impl WasmDocument { #[wasm_bindgen(js_name = insertMethod)] pub fn insert_method(&mut self, method: &WasmVerificationMethod, scope: Option) -> Result { - let scope: MethodScope = scope.unwrap_or_default().parse().map_err(err)?; + let scope: MethodScope = scope.unwrap_or_default().parse().map_err(wasm_error)?; Ok(self.0.insert_method(scope, method.0.clone())) } #[wasm_bindgen(js_name = removeMethod)] pub fn remove_method(&mut self, did: &WasmDID) -> Result<(), JsValue> { - self.0.remove_method(&did.0).map_err(err) + self.0.remove_method(&did.0).map_err(wasm_error) } #[wasm_bindgen(js_name = insertService)] @@ -156,7 +156,7 @@ impl WasmDocument { #[wasm_bindgen(js_name = removeService)] pub fn remove_service(&mut self, did: &WasmDID) -> Result<(), JsValue> { - self.0.remove_service(&did.0).map_err(err) + self.0.remove_service(&did.0).map_err(wasm_error) } // =========================================================================== @@ -166,7 +166,7 @@ impl WasmDocument { /// Signs the DID Document with the default authentication method. #[wasm_bindgen] pub fn sign(&mut self, key: &KeyPair) -> Result<(), JsValue> { - self.0.sign(key.0.secret()).map_err(err) + self.0.sign(key.0.secret()).map_err(wasm_error) } /// Verify the signature with the authentication_key @@ -213,8 +213,8 @@ impl WasmDocument { }, } - let mut data: verifiable::Properties = data.into_serde().map_err(err)?; - let args: Args = args.into_serde().map_err(err)?; + let mut data: verifiable::Properties = data.into_serde().map_err(wasm_error)?; + let args: Args = args.into_serde().map_err(wasm_error)?; match args { Args::MerkleKey { @@ -227,38 +227,46 @@ impl WasmDocument { .0 .try_resolve(&*method) .and_then(|method| method.key_data().try_decode().map_err(Error::InvalidDoc)) - .map_err(err)?; + .map_err(wasm_error)?; - let public: PublicKey = decode_b58(&public).map_err(err).map(Into::into)?; - let secret: SecretKey = decode_b58(&secret).map_err(err).map(Into::into)?; + let public: PublicKey = decode_b58(&public).map_err(wasm_error).map(Into::into)?; + let secret: SecretKey = decode_b58(&secret).map_err(wasm_error).map(Into::into)?; - let digest: MerkleDigestTag = MerkleKey::extract_tags(&merkle_key).map_err(err)?.1; - let proof: Vec = decode_b58(&proof).map_err(err)?; + let digest: MerkleDigestTag = MerkleKey::extract_tags(&merkle_key).map_err(wasm_error)?.1; + let proof: Vec = decode_b58(&proof).map_err(wasm_error)?; let signer: _ = self.0.signer(&secret).method(&method); match digest { MerkleDigestTag::SHA256 => match Proof::::decode(&proof) { - Some(proof) => signer.merkle_key((&public, &proof)).sign(&mut data).map_err(err)?, + Some(proof) => signer + .merkle_key((&public, &proof)) + .sign(&mut data) + .map_err(wasm_error)?, None => return Err("Invalid Public Key Proof".into()), }, _ => return Err("Invalid Merkle Key Digest".into()), } } Args::Default { method, secret } => { - let secret: SecretKey = decode_b58(&secret).map_err(err).map(Into::into)?; + let secret: SecretKey = decode_b58(&secret).map_err(wasm_error).map(Into::into)?; - self.0.signer(&secret).method(&method).sign(&mut data).map_err(err)?; + self + .0 + .signer(&secret) + .method(&method) + .sign(&mut data) + .map_err(wasm_error)?; } } - JsValue::from_serde(&data).map_err(err) + JsValue::from_serde(&data).map_err(wasm_error) } /// Verifies the authenticity of `data` using the target verification method. #[wasm_bindgen(js_name = verifyData)] pub fn verify_data(&self, data: &JsValue) -> Result { - let data: verifiable::Properties = data.into_serde().map_err(err)?; + let data: verifiable::Properties = data.into_serde().map_err(wasm_error)?; let result: bool = self.0.verifier().verify(&data).is_ok(); Ok(result) @@ -266,7 +274,9 @@ impl WasmDocument { #[wasm_bindgen(js_name = resolveKey)] pub fn resolve_key(&mut self, query: &str) -> Result { - Ok(WasmVerificationMethod(self.0.try_resolve(query).map_err(err)?.clone())) + Ok(WasmVerificationMethod( + self.0.try_resolve(query).map_err(wasm_error)?.clone(), + )) } #[wasm_bindgen(js_name = revokeMerkleKey)] @@ -275,9 +285,9 @@ impl WasmDocument { .0 .try_resolve_mut(query) .and_then(IotaVerificationMethod::try_from_mut) - .map_err(err)?; + .map_err(wasm_error)?; - method.revoke_merkle_key(index).map_err(err) + method.revoke_merkle_key(index).map_err(wasm_error) } // =========================================================================== @@ -289,17 +299,21 @@ impl WasmDocument { pub fn diff(&self, other: &WasmDocument, message: &str, key: &KeyPair) -> Result { self .0 - .diff(&other.0, MessageId::from_str(message).map_err(err)?, key.0.secret()) - .map_err(err) - .and_then(|diff| JsValue::from_serde(&diff).map_err(err)) + .diff( + &other.0, + MessageId::from_str(message).map_err(wasm_error)?, + key.0.secret(), + ) + .map_err(wasm_error) + .and_then(|diff| JsValue::from_serde(&diff).map_err(wasm_error)) } /// Verifies the `diff` signature and merges the changes into `self`. #[wasm_bindgen] pub fn merge(&mut self, diff: &str) -> Result<(), JsValue> { - let diff: DocumentDiff = DocumentDiff::from_json(diff).map_err(err)?; + let diff: DocumentDiff = DocumentDiff::from_json(diff).map_err(wasm_error)?; - self.0.merge(&diff).map_err(err)?; + self.0.merge(&diff).map_err(wasm_error)?; Ok(()) } @@ -307,12 +321,12 @@ impl WasmDocument { /// Serializes a `Document` object as a JSON object. #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } /// Deserializes a `Document` object from a JSON object. #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(json: &JsValue) -> Result { - json.into_serde().map_err(err).map(Self) + json.into_serde().map_err(wasm_error).map(Self) } } diff --git a/bindings/wasm/src/wasm_verification_method.rs b/bindings/wasm/src/wasm_verification_method.rs index af763ce042..c81295a9c7 100644 --- a/bindings/wasm/src/wasm_verification_method.rs +++ b/bindings/wasm/src/wasm_verification_method.rs @@ -10,7 +10,7 @@ use wasm_bindgen::prelude::*; use crate::crypto::Digest; use crate::crypto::KeyCollection; use crate::crypto::KeyPair; -use crate::utils::err; +use crate::error::wasm_error; use crate::wasm_did::WasmDID; #[wasm_bindgen(js_name = VerificationMethod, inspectable)] @@ -23,7 +23,7 @@ impl WasmVerificationMethod { #[wasm_bindgen(constructor)] pub fn new(key: &KeyPair, tag: Option) -> Result { IotaVerificationMethod::from_keypair(&key.0, tag.as_deref()) - .map_err(err) + .map_err(wasm_error) .map(Self) } @@ -31,7 +31,7 @@ impl WasmVerificationMethod { #[wasm_bindgen(js_name = fromDID)] pub fn from_did(did: &WasmDID, key: &KeyPair, tag: Option) -> Result { IotaVerificationMethod::from_did(did.0.clone(), &key.0, tag.as_deref()) - .map_err(err) + .map_err(wasm_error) .map(Self) } @@ -48,10 +48,10 @@ impl WasmVerificationMethod { match digest { Digest::Sha256 => IotaVerificationMethod::create_merkle_key::(did, &keys.0, tag) - .map_err(err) + .map_err(wasm_error) .map(Self), Digest::Blake2b256 => IotaVerificationMethod::create_merkle_key::(did, &keys.0, tag) - .map_err(err) + .map_err(wasm_error) .map(Self), } } @@ -77,18 +77,18 @@ impl WasmVerificationMethod { /// Returns the `VerificationMethod` public key data. #[wasm_bindgen(getter)] pub fn data(&self) -> Result { - JsValue::from_serde(self.0.key_data()).map_err(err) + JsValue::from_serde(self.0.key_data()).map_err(wasm_error) } /// Serializes a `VerificationMethod` object as a JSON object. #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self) -> Result { - JsValue::from_serde(&self.0).map_err(err) + JsValue::from_serde(&self.0).map_err(wasm_error) } /// Deserializes a `VerificationMethod` object from a JSON object. #[wasm_bindgen(js_name = fromJSON)] pub fn from_json(value: &JsValue) -> Result { - value.into_serde().map_err(err).map(Self) + value.into_serde().map_err(wasm_error).map(Self) } } diff --git a/bindings/wasm/tests/wasm.rs b/bindings/wasm/tests/wasm.rs index d97fdbe099..cb0ff64f5a 100644 --- a/bindings/wasm/tests/wasm.rs +++ b/bindings/wasm/tests/wasm.rs @@ -7,8 +7,10 @@ use identity_wasm::crypto::Digest; use identity_wasm::crypto::KeyCollection; use identity_wasm::crypto::KeyPair; use identity_wasm::crypto::KeyType; +use identity_wasm::error::WasmError; use identity_wasm::wasm_did::WasmDID; use identity_wasm::wasm_document::WasmDocument; +use std::borrow::Cow; #[wasm_bindgen_test] fn test_keypair() { @@ -59,6 +61,14 @@ fn test_key_collection() { } } +#[wasm_bindgen_test] +fn test_js_error_from_wasm_error() { + let error = WasmError::new(Cow::Borrowed("Some name"), Cow::Owned("Error message".to_owned())); + let js_error = js_sys::Error::from(error); + assert_eq!(js_error.name(), "Some name"); + assert_eq!(js_error.message(), "Error message"); +} + #[test] fn test_did() { let key = KeyPair::new(KeyType::Ed25519).unwrap(); diff --git a/identity-account/Cargo.toml b/identity-account/Cargo.toml index 175c21cf9d..4c784e89cc 100644 --- a/identity-account/Cargo.toml +++ b/identity-account/Cargo.toml @@ -28,6 +28,7 @@ serde = { version = "1.0", default-features = false, features = [ "derive" ] } slog = { version = "2.7" } +strum = { version = "0.21", features = ["derive"] } thiserror = { version = "1.0" } tokio = { version = "1.5", features = ["sync"] } zeroize = { version = "1.3" } diff --git a/identity-account/src/error.rs b/identity-account/src/error.rs index 606867c288..1050313e80 100644 --- a/identity-account/src/error.rs +++ b/identity-account/src/error.rs @@ -7,7 +7,7 @@ pub type Result = ::core::result::Result; /// This type represents all possible errors that can occur in the library. -#[derive(Debug, thiserror::Error)] +#[derive(Debug, thiserror::Error, strum::IntoStaticStr)] pub enum Error { /// Caused by errors from the [crypto] crate. #[error(transparent)] diff --git a/identity-comm/Cargo.toml b/identity-comm/Cargo.toml index ef3edaa200..c3116a70f6 100644 --- a/identity-comm/Cargo.toml +++ b/identity-comm/Cargo.toml @@ -19,6 +19,7 @@ libjose = { path = "../libjose", version = "=0.1.0" } paste = { version = "1.0" } serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0" } +strum = { version = "0.21", features = ["derive"] } thiserror = { version = "1.0" } uuid = { version = "0.8", features = ["serde", "v4"], default-features = false } diff --git a/identity-comm/src/error.rs b/identity-comm/src/error.rs index a632e9c40d..6397c7e5e8 100644 --- a/identity-comm/src/error.rs +++ b/identity-comm/src/error.rs @@ -3,7 +3,7 @@ pub type Result = core::result::Result; -#[derive(Debug, thiserror::Error)] +#[derive(Debug, thiserror::Error, strum::IntoStaticStr)] pub enum Error { #[error(transparent)] IotaError(#[from] identity_iota::Error), diff --git a/identity-core/Cargo.toml b/identity-core/Cargo.toml index 04cf9a73a7..d9c493117e 100644 --- a/identity-core/Cargo.toml +++ b/identity-core/Cargo.toml @@ -13,7 +13,7 @@ homepage = "https://www.iota.org" [dependencies] base64 = { version = "0.13", default-features = false, features = ["std"] } bs58 = { version = "0.4", default-features = false, features = ["std"] } -multibase = { version ="0.9", default-features = false, features = ["std"] } +multibase = { version = "0.9", default-features = false, features = ["std"] } chrono = { version = "0.4", default-features = false, features = ["clock", "std"] } hex = { version = "0.4", default-features = false } identity-diff = { version = "=0.3.0", path = "../identity-diff", default-features = false } @@ -22,6 +22,7 @@ serde = { version = "1.0", default-features = false, features = ["std", "derive" serde_jcs = { version = "0.1", default-features = false } serde_json = { version = "1.0", default-features = false, features = ["std"] } subtle = { version = "2.4", default-features = false } +strum = { version = "0.21", features = ["derive"] } thiserror = { version = "1.0", default-features = false } typenum = { version = "1.13", default-features = false } url = { version = "2.2", default-features = false, features = ["serde"] } diff --git a/identity-core/src/error.rs b/identity-core/src/error.rs index 8ab668e967..d7edb39e7c 100644 --- a/identity-core/src/error.rs +++ b/identity-core/src/error.rs @@ -10,7 +10,7 @@ use crate::crypto::merkle_key::MerkleDigestTag; use crate::crypto::merkle_key::MerkleSignatureTag; /// This type represents all possible errors that can occur in the library. -#[derive(Debug, thiserror::Error)] +#[derive(Debug, thiserror::Error, strum::IntoStaticStr)] pub enum Error { /// Caused when a cryptographic operation fails. #[error("Crypto Error: {0}")] diff --git a/identity-credential/Cargo.toml b/identity-credential/Cargo.toml index e28f583b78..b81835dbca 100644 --- a/identity-credential/Cargo.toml +++ b/identity-credential/Cargo.toml @@ -15,6 +15,7 @@ identity-core = { version = "=0.3.0", path = "../identity-core" } identity-did = { version = "=0.3.0", path = "../identity-did" } lazy_static = { version = "1.4", default-features = false } serde = { version = "1.0", default-features = false, features = ["std", "derive"] } +strum = { version = "0.21", features = ["derive"] } thiserror = { version = "1.0", default-features = false } [dev-dependencies] diff --git a/identity-credential/src/error.rs b/identity-credential/src/error.rs index 209def5cee..41f771b2ba 100644 --- a/identity-credential/src/error.rs +++ b/identity-credential/src/error.rs @@ -7,7 +7,7 @@ pub type Result = ::core::result::Result; /// This type represents all possible errors that can occur in the library. -#[derive(Debug, thiserror::Error)] +#[derive(Debug, thiserror::Error, strum::IntoStaticStr)] pub enum Error { /// Caused by errors from the [identity_did] crate. #[error("{0}")] diff --git a/identity-did/Cargo.toml b/identity-did/Cargo.toml index 59f6a76e80..686df20e3b 100644 --- a/identity-did/Cargo.toml +++ b/identity-did/Cargo.toml @@ -15,6 +15,7 @@ async-trait = { version = "0.1", default-features = false } did_url = { version = "0.1", default-features = false, features = ["std", "serde"] } identity-core = { version = "=0.3.0", path = "../identity-core" } serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] } +strum = { version = "0.21", features = ["derive"] } thiserror = { version = "1.0", default-features = false } [package.metadata.docs.rs] diff --git a/identity-did/src/error.rs b/identity-did/src/error.rs index 4d4ac55d98..fdca119d46 100644 --- a/identity-did/src/error.rs +++ b/identity-did/src/error.rs @@ -7,7 +7,7 @@ pub type Result = ::core::result::Result; /// This type represents all possible errors that can occur in the library. -#[derive(Debug, thiserror::Error)] +#[derive(Debug, thiserror::Error, strum::IntoStaticStr)] pub enum Error { /// Caused by errors from the [identity_core] crate. #[error("{0}")] diff --git a/identity-diff/Cargo.toml b/identity-diff/Cargo.toml index bd9ed15bd2..54bb80051d 100644 --- a/identity-diff/Cargo.toml +++ b/identity-diff/Cargo.toml @@ -13,8 +13,9 @@ homepage = "https://www.iota.org" [dependencies] did_url = { version = "0.1", default-features = false, features = ["alloc"] } identity-derive = { version = "=0.3.0", path = "derive" } -serde = { version = "1.0", features = [ "derive" ] } +serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0" } +strum = { version = "0.21", features = ["derive"] } thiserror = { version = "1.0" } [dev-dependencies] diff --git a/identity-diff/src/error.rs b/identity-diff/src/error.rs index 69bb462628..cb4c29cf55 100644 --- a/identity-diff/src/error.rs +++ b/identity-diff/src/error.rs @@ -5,7 +5,7 @@ use core::fmt::Display; pub type Result = ::core::result::Result; -#[derive(Debug, thiserror::Error)] +#[derive(Debug, thiserror::Error, strum::IntoStaticStr)] pub enum Error { #[error("Diff Error: {0}")] DiffError(String), diff --git a/identity-iota/Cargo.toml b/identity-iota/Cargo.toml index 4efec9e034..45e6d113c0 100644 --- a/identity-iota/Cargo.toml +++ b/identity-iota/Cargo.toml @@ -21,6 +21,7 @@ identity-did = { version = "=0.3.0", path = "../identity-did" } lazy_static = { version = "1.4", default-features = false } log = { version = "0.4", default-features = false } serde = { version = "1.0", default-features = false, features = ["std", "derive"] } +strum = { version = "0.21", features = ["derive"] } thiserror = { version = "1.0", default-features = false } [dependencies.iota-client] diff --git a/identity-iota/src/error.rs b/identity-iota/src/error.rs index 92f2b322f2..df787c29ff 100644 --- a/identity-iota/src/error.rs +++ b/identity-iota/src/error.rs @@ -3,7 +3,7 @@ pub type Result = core::result::Result; -#[derive(Debug, thiserror::Error)] +#[derive(Debug, thiserror::Error, strum::IntoStaticStr)] pub enum Error { #[error("{0}")] CoreError(#[from] identity_core::Error), diff --git a/identity-iota/src/tangle/mod.rs b/identity-iota/src/tangle/mod.rs index aec8f45084..7d2a2fa001 100644 --- a/identity-iota/src/tangle/mod.rs +++ b/identity-iota/src/tangle/mod.rs @@ -26,3 +26,7 @@ pub use iota_client::bee_message::Message; #[doc(inline)] pub use iota_client::bee_message::MessageId; + +// Re-export bee_message::Error to use it directly in bindings +#[doc(inline)] +pub use iota_client::bee_message::Error as BeeMessageError;