Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace failure crate with thiserror #684

Merged
merged 6 commits into from
Dec 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
329 changes: 147 additions & 182 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion agency_client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ reqwest = "0.11.10"
regex = "1.1.0"
rust-base58 = "0.0.4"
url = "2.3"
failure = "0.1.6"
uuid = { version = "0.8", default-features = false, features = ["v4"]}
thiserror = "1.0.37"

[target.'cfg(target_os = "android")'.dependencies]
android_logger = "0.5"
Expand Down
122 changes: 58 additions & 64 deletions agency_client/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,113 +1,100 @@
use std::fmt;
use std::error::Error;

use failure::{Backtrace, Context, Fail};
use thiserror;

use crate::utils::error_utils::kind_to_error_message;

pub mod prelude {
pub use super::*;
}

#[derive(Copy, Clone, Eq, PartialEq, Debug, Fail)]
#[derive(Copy, Clone, Eq, PartialEq, Debug, thiserror::Error)]
pub enum AgencyClientErrorKind {
// Common
#[fail(display = "Object is in invalid state for requested operation")]
#[error("Object is in invalid state for requested operation")]
InvalidState,
#[fail(display = "Invalid Configuration")]
#[error("Invalid Configuration")]
InvalidConfiguration,
#[fail(display = "Obj was not found with handle")]
#[error("Obj was not found with handle")]
InvalidJson,
#[fail(display = "Invalid Option")]
#[error("Invalid Option")]
InvalidOption,
#[fail(display = "Invalid MessagePack")]
#[error("Invalid MessagePack")]
InvalidMessagePack,
#[fail(display = "IO Error, possibly creating a backup wallet")]
#[error("IO Error, possibly creating a backup wallet")]
IOError,
#[fail(display = "Object (json, config, key, credential and etc...) passed to libindy has invalid structure")]
#[error("Object (json, config, key, credential and etc...) passed to libindy has invalid structure")]
LibindyInvalidStructure,
#[fail(display = "Waiting for callback timed out")]
#[error("Waiting for callback timed out")]
TimeoutLibindy,
#[fail(display = "Parameter passed to libindy was invalid")]
#[error("Parameter passed to libindy was invalid")]
InvalidLibindyParam,

#[fail(display = "Message failed in post")]
#[error("Message failed in post")]
PostMessageFailed,

// Wallet
#[fail(display = "Invalid Wallet or Search Handle")]
#[error("Invalid Wallet or Search Handle")]
InvalidWalletHandle,
#[fail(display = "Indy wallet already exists")]
#[error("Indy wallet already exists")]
DuplicationWallet,
#[fail(display = "Wallet record not found")]
#[error("Wallet record not found")]
WalletRecordNotFound,
#[fail(display = "Record already exists in the wallet")]
#[error("Record already exists in the wallet")]
DuplicationWalletRecord,
#[fail(display = "Wallet not found")]
#[error("Wallet not found")]
WalletNotFound,
#[fail(display = "Indy wallet already open")]
#[error("Indy wallet already open")]
WalletAlreadyOpen,
#[fail(display = "Configuration is missing wallet key")]
#[error("Configuration is missing wallet key")]
MissingWalletKey,
#[fail(display = "Attempted to add a Master Secret that already existed in wallet")]
#[error("Attempted to add a Master Secret that already existed in wallet")]
DuplicationMasterSecret,
#[fail(display = "Attempted to add a DID to wallet when that DID already exists in wallet")]
#[error("Attempted to add a DID to wallet when that DID already exists in wallet")]
DuplicationDid,

// Validation
#[fail(display = "Unknown Error")]
#[error("Unknown Error")]
UnknownError,
#[fail(display = "Invalid DID")]
#[error("Invalid DID")]
InvalidDid,
#[fail(display = "Invalid VERKEY")]
#[error("Invalid VERKEY")]
InvalidVerkey,
#[fail(display = "Invalid URL")]
#[error("Invalid URL")]
InvalidUrl,
#[fail(display = "Unable to serialize")]
#[error("Unable to serialize")]
SerializationError,
#[fail(display = "Value needs to be base58")]
#[error("Value needs to be base58")]
NotBase58,

// A2A
#[fail(display = "Invalid HTTP response.")]
#[error("Invalid HTTP response.")]
InvalidHttpResponse,

#[fail(display = "Failed to create agency client")]
#[error("Failed to create agency client")]
CreateAgent,

#[fail(display = "Libndy error {}", 0)]
#[error("Libndy error {}", 0)]
LibndyError(u32),
#[fail(display = "Unknown libindy error")]
#[error("Unknown libindy error")]
UnknownLibndyError,
}

#[derive(Debug)]
#[derive(Debug, thiserror::Error)]
pub struct AgencyClientError {
inner: Context<AgencyClientErrorKind>,
}

impl Fail for AgencyClientError {
fn cause(&self) -> Option<&dyn Fail> {
self.inner.cause()
}

fn backtrace(&self) -> Option<&Backtrace> {
self.inner.backtrace()
}
msg: String,
kind: AgencyClientErrorKind,
}

impl fmt::Display for AgencyClientError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut first = true;

for cause in <dyn Fail>::iter_chain(&self.inner) {
if first {
first = false;
writeln!(f, "Error: {}", cause)?;
} else {
writeln!(f, " Caused by: {}", cause)?;
}
writeln!(f, "Error: {}\n", self.msg)?;
let mut current = self.source();
while let Some(cause) = current {
writeln!(f, "Caused by:\n\t{}", cause)?;
current = cause.source();
}

Ok(())
}
}
Expand All @@ -118,21 +105,32 @@ impl AgencyClientError {
D: fmt::Display + fmt::Debug + Send + Sync + 'static,
{
AgencyClientError {
inner: Context::new(msg).context(kind),
msg: msg.to_string(),
kind,
}
}

pub fn find_root_cause(&self) -> String {
let mut current = self.source();
while let Some(cause) = current {
if cause.source().is_none() { return cause.to_string() }
current = cause.source();
}
self.to_string()
}


pub fn kind(&self) -> AgencyClientErrorKind {
*self.inner.get_context()
self.kind
}

pub fn extend<D>(self, msg: D) -> AgencyClientError
where
D: fmt::Display + fmt::Debug + Send + Sync + 'static,
{
let kind = self.kind();
AgencyClientError {
inner: self.inner.map(|_| msg).context(kind),
msg: msg.to_string(),
..self
}
}

Expand All @@ -141,7 +139,9 @@ impl AgencyClientError {
D: fmt::Display + fmt::Debug + Send + Sync + 'static,
{
AgencyClientError {
inner: self.inner.map(|_| msg).context(kind),
msg: msg.to_string(),
kind,
..self
}
}
}
Expand All @@ -152,12 +152,6 @@ impl From<AgencyClientErrorKind> for AgencyClientError {
}
}

impl From<Context<AgencyClientErrorKind>> for AgencyClientError {
fn from(inner: Context<AgencyClientErrorKind>) -> AgencyClientError {
AgencyClientError { inner }
}
}

impl From<serde_json::Error> for AgencyClientError {
fn from(_err: serde_json::Error) -> Self {
AgencyClientErrorKind::InvalidJson.into()
Expand Down
2 changes: 1 addition & 1 deletion agents/rust/aries-vcx-agent/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ version = "0.1.0"
edition = "2021"

[dependencies]
failure = "0.1.8"
serde = "1.0.145"
aries-vcx = { path = "../../../aries_vcx" }
derive_builder = "0.11.2"
serde_json = "1.0.85"
log = "0.4.17"
uuid = "1.2.1"
thiserror = "1.0.37"
20 changes: 9 additions & 11 deletions agents/rust/aries-vcx-agent/src/error/error_kind.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
use failure::Fail;

#[derive(Copy, Clone, Eq, PartialEq, Debug, Fail)]
#[derive(Copy, Clone, Eq, PartialEq, Debug, thiserror::Error)]
pub enum AgentErrorKind {
#[fail(display = "AriesVCX error")]
#[error("AriesVCX error")]
GenericAriesVcxError,
#[fail(display = "Failed to get invite details")]
#[error("Failed to get invite details")]
InviteDetails,
#[fail(display = "No object found with specified ID")]
#[error("No object found with specified ID")]
NotFound,
#[fail(display = "Unable to lock storage")]
#[error("Unable to lock storage")]
LockError,
#[fail(display = "Serialization error")]
#[error("Serialization error")]
SerializationError,
#[fail(display = "Invalid arguments passed")]
#[error("Invalid arguments passed")]
InvalidArguments,
#[fail(display = "Credential definition already exists on the ledger")]
#[error("Credential definition already exists on the ledger")]
CredDefAlreadyCreated,
#[fail(display = "Mediated connections not configured")]
#[error("Mediated connections not configured")]
MediatedConnectionServiceUnavailable,
}
2 changes: 1 addition & 1 deletion aries_vcx/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@ indy-credx = { git = "https://github.com/anonyome/indy-shared-rs.git", rev = "73
futures = { version = "0.3", default-features = false }
libloading = "0.5.0"
uuid = { version = "0.8", default-features = false, features = ["v4"]}
failure = "0.1.6"
strum = "0.16.0"
strum_macros = "0.16.0"
agency_client = { path = "../agency_client" }
derive_builder = "0.10.2"
tokio = { version = "1.15.0" }
messages = { path = "../messages" }
zmq = { version = "0.9.2" }
thiserror = "1.0.37"

[target.'cfg(target_os = "android")'.dependencies]
android_logger = "0.5"
Expand Down
9 changes: 7 additions & 2 deletions aries_vcx/src/common/ledger/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use serde_json::Value;
use crate::{
common::keys::get_verkey_from_ledger,
core::profile::profile::Profile,
error::{VcxError, VcxErrorKind, VcxResult, VcxResultExt},
error::{VcxError, VcxErrorKind, VcxResult},
global::settings,
};

Expand Down Expand Up @@ -200,7 +200,12 @@ pub(self) fn check_response(response: &str) -> VcxResult<()> {

fn parse_response(response: &str) -> VcxResult<Response> {
serde_json::from_str::<Response>(response)
.to_vcx(VcxErrorKind::InvalidJson, "Cannot deserialize transaction response")
.map_err(|err|
VcxError::from_msg(
VcxErrorKind::InvalidJson,
format!("Cannot deserialize transaction response: {:?}", err)
)
)
}

fn get_data_from_response(resp: &str) -> VcxResult<serde_json::Value> {
Expand Down