diff --git a/Cargo.lock b/Cargo.lock index e66818460c..312e0bd065 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1694,6 +1694,8 @@ dependencies = [ "async-trait", "did_resolver", "mockall", + "serde", + "serde_json", "tokio", ] @@ -2617,10 +2619,10 @@ dependencies = [ name = "indy-ledger-response-parser" version = "0.1.0" dependencies = [ - "indy-api-types", "indy-vdr", "serde", "serde_json", + "thiserror", "time 0.3.20", "ursa", ] diff --git a/indy_ledger_response_parser/Cargo.toml b/indy_ledger_response_parser/Cargo.toml index 257a0b0b57..cf78808fcb 100644 --- a/indy_ledger_response_parser/Cargo.toml +++ b/indy_ledger_response_parser/Cargo.toml @@ -8,5 +8,5 @@ serde = { version = "1.0.163", features = ["derive"] } serde_json = "1.0.96" time = "=0.3.20" ursa = { version = "0.3.7" } -indy-api-types = { path = "../libvdrtools/indy-api-types" } indy-vdr = { git = "https://github.com/Patrik-Stas/indy-vdr.git", rev = "3cd499ad75", default-features = false, features = ["log"] } +thiserror = "1.0.44" diff --git a/indy_ledger_response_parser/src/domain/response.rs b/indy_ledger_response_parser/src/domain/response.rs index be291f50c2..ca5f11ed78 100644 --- a/indy_ledger_response_parser/src/domain/response.rs +++ b/indy_ledger_response_parser/src/domain/response.rs @@ -1,7 +1,4 @@ -use indy_api_types::{ - errors::{err_msg, IndyErrorKind}, - IndyError, -}; +use crate::error::LedgerResponseParserError; #[derive(Deserialize, Debug)] #[serde(rename_all = "camelCase")] @@ -107,10 +104,16 @@ impl<'a, T> TryFrom>> for ReplyV0 where T: ReplyType, { - type Error = IndyError; + type Error = LedgerResponseParserError; + fn try_from(value: ReplyV0>) -> Result { - if value.result.type_ != T::get_type() { - Err(err_msg(IndyErrorKind::InvalidTransaction, "Invalid response type")) + let expected_type = T::get_type(); + let actual_type = value.result.type_; + if expected_type != actual_type { + Err(LedgerResponseParserError::InvalidTransaction(format!( + "Unexpected response type:\nExpected: {}\nActual: {}", + expected_type, actual_type + ))) } else { Ok(ReplyV0 { result: value.result.reply, @@ -123,7 +126,7 @@ impl<'a, T> TryFrom>> for ReplyV1 where T: ReplyType, { - type Error = IndyError; + type Error = LedgerResponseParserError; fn try_from(value: ReplyV1>) -> Result { let value = value @@ -131,7 +134,7 @@ where .result .into_iter() .next() - .ok_or_else(|| err_msg(IndyErrorKind::InvalidTransaction, "Invalid response type"))?; + .ok_or_else(|| LedgerResponseParserError::InvalidTransaction("Result field is empty".to_string()))?; let data = ReplyDataV1 { result: [value.try_into()?], }; @@ -143,7 +146,7 @@ impl<'a, T> TryFrom>> for Reply where T: ReplyType, { - type Error = IndyError; + type Error = LedgerResponseParserError; fn try_from(value: Reply>) -> Result { let reply = match value { @@ -158,7 +161,7 @@ impl<'a, T> TryFrom> for Message where T: ReplyType, { - type Error = IndyError; + type Error = LedgerResponseParserError; fn try_from(value: MessageWithTypedReply<'a, T>) -> Result { match value { diff --git a/indy_ledger_response_parser/src/error.rs b/indy_ledger_response_parser/src/error.rs new file mode 100644 index 0000000000..1cf94b7648 --- /dev/null +++ b/indy_ledger_response_parser/src/error.rs @@ -0,0 +1,11 @@ +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum LedgerResponseParserError { + #[error("JSON error: {0}")] + JsonError(#[from] serde_json::error::Error), + #[error("Ledger item not found: {0}")] + LedgerItemNotFound(&'static str), + #[error("Invalid transaction: {0}")] + InvalidTransaction(String), +} diff --git a/indy_ledger_response_parser/src/lib.rs b/indy_ledger_response_parser/src/lib.rs index f690710c5c..28e4d56358 100644 --- a/indy_ledger_response_parser/src/lib.rs +++ b/indy_ledger_response_parser/src/lib.rs @@ -7,11 +7,7 @@ mod domain; pub use domain::author_agreement::GetTxnAuthorAgreementData; use domain::author_agreement::GetTxnAuthorAgreementResult; -pub use indy_api_types::{errors, ErrorCode}; -use indy_api_types::{ - errors::{err_msg, IndyErrorKind, IndyResult, IndyResultExt}, - IndyError, -}; +use error::LedgerResponseParserError; use indy_vdr::{ ledger::{ identifiers::{CredentialDefinitionId, RevocationRegistryId, SchemaId}, @@ -56,22 +52,15 @@ impl ResponseParser { Self {} } - pub fn parse_get_nym_response(&self, get_nym_response: &str) -> IndyResult { + pub fn parse_get_nym_response(&self, get_nym_response: &str) -> Result { let reply: Reply = Self::parse_response(get_nym_response)?; let nym_data = match reply.result() { GetNymReplyResult::GetNymReplyResultV0(res) => { let data: GetNymResultDataV0 = res .data - .ok_or_else(|| IndyError::from_msg(IndyErrorKind::LedgerItemNotFound, format!("Nym not found"))) - .and_then(|data| { - serde_json::from_str(&data).map_err(|err| { - IndyError::from_msg( - IndyErrorKind::InvalidState, - format!("Cannot parse GET_NYM response: {}", err), - ) - }) - })?; + .ok_or_else(|| LedgerResponseParserError::LedgerItemNotFound("NYM")) + .and_then(|data| serde_json::from_str(&data).map_err(Into::into))?; NymData { did: data.dest, @@ -93,7 +82,7 @@ impl ResponseParser { &self, get_schema_response: &str, method_name: Option<&str>, - ) -> IndyResult { + ) -> Result { let reply: Reply = Self::parse_response(get_schema_response)?; let schema = match reply.result() { @@ -128,7 +117,7 @@ impl ResponseParser { &self, get_cred_def_response: &str, method_name: Option<&str>, - ) -> IndyResult { + ) -> Result { let reply: Reply = Self::parse_response(get_cred_def_response)?; let cred_def = match reply.result() { @@ -159,7 +148,7 @@ impl ResponseParser { pub fn parse_get_revoc_reg_def_response( &self, get_revoc_reg_def_response: &str, - ) -> IndyResult { + ) -> Result { let reply: Reply = Self::parse_response(get_revoc_reg_def_response)?; let revoc_reg_def = match reply.result() { @@ -172,7 +161,10 @@ impl ResponseParser { )) } - pub fn parse_get_revoc_reg_response(&self, get_revoc_reg_response: &str) -> IndyResult { + pub fn parse_get_revoc_reg_response( + &self, + get_revoc_reg_response: &str, + ) -> Result { let reply: Reply = Self::parse_response(get_revoc_reg_response)?; let (revoc_reg_def_id, revoc_reg, timestamp) = match reply.result() { @@ -191,13 +183,16 @@ impl ResponseParser { }) } - pub fn parse_get_txn_author_agreement_response(&self, taa_response: &str) -> IndyResult { + pub fn parse_get_txn_author_agreement_response( + &self, + taa_response: &str, + ) -> Result { let reply: Reply = Self::parse_response(taa_response)?; let data = match reply.result() { GetTxnAuthorAgreementResult::GetTxnAuthorAgreementResultV1(res) => res .data - .ok_or_else(|| IndyError::from_msg(IndyErrorKind::LedgerItemNotFound, "TAA not found"))?, + .ok_or_else(|| LedgerResponseParserError::LedgerItemNotFound("TAA"))?, }; Ok(GetTxnAuthorAgreementData { @@ -212,7 +207,7 @@ impl ResponseParser { pub fn parse_get_revoc_reg_delta_response( &self, get_revoc_reg_delta_response: &str, - ) -> IndyResult { + ) -> Result { let reply: Reply = Self::parse_response(get_revoc_reg_delta_response)?; let (revoc_reg_def_id, revoc_reg) = match reply.result() { @@ -228,11 +223,7 @@ impl ResponseParser { &revoc_reg.value.accum_to.value, &revoc_reg.value.issued, &revoc_reg.value.revoked, - )) - .to_indy( - IndyErrorKind::InvalidStructure, - "Cannot convert RevocationRegistryDelta to Value", - )?, + ))?, }; Ok(RevocationRegistryDeltaInfo { @@ -242,20 +233,16 @@ impl ResponseParser { }) } - pub fn parse_response(response: &str) -> IndyResult> + pub fn parse_response(response: &str) -> Result, LedgerResponseParserError> where T: DeserializeOwned + ReplyType + ::std::fmt::Debug, { - let message: Message = serde_json::from_str(response).to_indy( - IndyErrorKind::LedgerItemNotFound, - "Structure doesn't correspond to type. Most probably not found", - )?; // FIXME: Review how we handle not found + let message: Message = serde_json::from_str(response)?; match message { - Message::Reject(response) | Message::ReqNACK(response) => Err(err_msg( - IndyErrorKind::InvalidTransaction, - format!("Transaction has been failed: {:?}", response.reason), - )), + Message::Reject(response) | Message::ReqNACK(response) => { + Err(LedgerResponseParserError::InvalidTransaction(response.reason)) + } Message::Reply(reply) => Ok(reply), } }