wallet: rewrite some abci errors on the fly (#2716)
* wallet: rewrite some abci errors on the fly * changelog: update * Tidy
This commit is contained in:
@@ -108,7 +108,7 @@ async fn test_nymd_connection(
|
||||
log::debug!("Checking: nymd_url: {url}: {}: {}", "failed".red(), e);
|
||||
false
|
||||
}
|
||||
Ok(Err(NymdError::AbciError(code, log))) => {
|
||||
Ok(Err(NymdError::AbciError { code, log, .. })) => {
|
||||
// We accept the mixnet contract not found as ok from a connection standpoint. This happens
|
||||
// for example on a pre-launch network.
|
||||
log::debug!(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::nymd;
|
||||
use crate::nymd::coin::Coin;
|
||||
use crate::nymd::cosmwasm_client::helpers::{create_pagination, next_page_key};
|
||||
use crate::nymd::cosmwasm_client::types::{
|
||||
@@ -23,7 +24,6 @@ use cosmrs::rpc::endpoint::broadcast;
|
||||
use cosmrs::rpc::endpoint::tx::Response as TxResponse;
|
||||
use cosmrs::rpc::query::Query;
|
||||
use cosmrs::rpc::{self, HttpClient, Order};
|
||||
use cosmrs::tendermint::abci::Code as AbciCode;
|
||||
use cosmrs::tendermint::abci::Transaction;
|
||||
use cosmrs::tendermint::{abci, block, chain};
|
||||
use cosmrs::{tx, AccountId, Coin as CosmosCoin, Tx};
|
||||
@@ -66,13 +66,9 @@ pub trait CosmWasmClient: rpc::Client {
|
||||
req.encode(&mut buf)?;
|
||||
|
||||
let res = self.abci_query(path, buf, None, false).await?;
|
||||
let res_success = nymd::error::parse_abci_query_result(res)?;
|
||||
|
||||
match res.code {
|
||||
AbciCode::Err(code) => return Err(NymdError::AbciError(code, res.log)),
|
||||
AbciCode::Ok => (),
|
||||
}
|
||||
|
||||
Ok(Res::decode(res.value.as_ref())?)
|
||||
Ok(Res::decode(res_success.value.as_ref())?)
|
||||
}
|
||||
|
||||
async fn get_chain_id(&self) -> Result<chain::Id, NymdError> {
|
||||
|
||||
@@ -2,16 +2,23 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::nymd::cosmwasm_client::types::ContractCodeId;
|
||||
use cosmrs::tendermint::{abci, block};
|
||||
use cosmrs::{bip32, tx, AccountId};
|
||||
use std::io;
|
||||
use std::time::Duration;
|
||||
use cosmrs::{
|
||||
bip32,
|
||||
rpc::endpoint::abci_query::AbciQuery,
|
||||
tendermint::{
|
||||
abci::{self, Code as AbciCode},
|
||||
block,
|
||||
},
|
||||
tx, AccountId,
|
||||
};
|
||||
use thiserror::Error;
|
||||
|
||||
pub use cosmrs::rpc::error::{
|
||||
Error as TendermintRpcError, ErrorDetail as TendermintRpcErrorDetail,
|
||||
use std::{io, time::Duration};
|
||||
|
||||
pub use cosmrs::rpc::{
|
||||
error::{Error as TendermintRpcError, ErrorDetail as TendermintRpcErrorDetail},
|
||||
response_error::{Code, ResponseError},
|
||||
};
|
||||
pub use cosmrs::rpc::response_error::{Code, ResponseError};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum NymdError {
|
||||
@@ -110,8 +117,12 @@ pub enum NymdError {
|
||||
#[error("Failed to estimate gas price for the transaction")]
|
||||
GasEstimationFailure,
|
||||
|
||||
#[error("Abci query failed with code {0} - {1}")]
|
||||
AbciError(u32, abci::Log),
|
||||
#[error("Abci query failed with code {code} - {log}")]
|
||||
AbciError {
|
||||
code: u32,
|
||||
log: abci::Log,
|
||||
pretty_log: Option<String>,
|
||||
},
|
||||
|
||||
#[error("Unsupported account type: {type_url}")]
|
||||
UnsupportedAccountType { type_url: String },
|
||||
@@ -135,6 +146,32 @@ pub enum NymdError {
|
||||
UnexpectedBech32Prefix { got: String, expected: String },
|
||||
}
|
||||
|
||||
// The purpose of parsing the abci query result is that we want to generate the `pretty_log` if
|
||||
// possible.
|
||||
pub fn parse_abci_query_result(query_result: AbciQuery) -> Result<AbciQuery, NymdError> {
|
||||
match query_result.code {
|
||||
AbciCode::Ok => Ok(query_result),
|
||||
AbciCode::Err(code) => Err(NymdError::AbciError {
|
||||
code,
|
||||
log: query_result.log.clone(),
|
||||
pretty_log: try_parse_abci_log(&query_result.log),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
// Some of the error strings returned by the query are a bit too technical to present to the
|
||||
// enduser. So we special case some commonly encountered errors.
|
||||
fn try_parse_abci_log(log: &abci::Log) -> Option<String> {
|
||||
if log
|
||||
.value()
|
||||
.contains("Maximum amount of locked coins has already been pledged")
|
||||
{
|
||||
Some("Maximum amount of locked tokens has alredy been used. You can only use up tp 10% of your locked tokens for bonding and delegating.".to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl NymdError {
|
||||
pub fn is_tendermint_response_timeout(&self) -> bool {
|
||||
match &self {
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
## UNRELEASED
|
||||
|
||||
- wallet: present some cases of the more technical errors (abci, ..) in a more human readable form.
|
||||
|
||||
## [nym-wallet-v1.1.3](https://github.com/nymtech/nym/releases/tag/nym-wallet-v1.1.3) (2022-12-13)
|
||||
|
||||
- wallet: improved unbond screen.
|
||||
|
||||
@@ -24,9 +24,10 @@ pub enum BackendError {
|
||||
#[from]
|
||||
source: tendermint_rpc::Error,
|
||||
},
|
||||
#[error("{source}")]
|
||||
#[error("{pretty_error}")]
|
||||
NymdError {
|
||||
#[from]
|
||||
pretty_error: String,
|
||||
#[source]
|
||||
source: NymdError,
|
||||
},
|
||||
#[error("{source}")]
|
||||
@@ -131,6 +132,34 @@ impl Serialize for BackendError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NymdError> for BackendError {
|
||||
fn from(source: NymdError) -> Self {
|
||||
match source {
|
||||
NymdError::AbciError {
|
||||
code: _,
|
||||
log: _,
|
||||
ref pretty_log,
|
||||
} => {
|
||||
if let Some(pretty_log) = pretty_log {
|
||||
Self::NymdError {
|
||||
pretty_error: pretty_log.to_string(),
|
||||
source,
|
||||
}
|
||||
} else {
|
||||
Self::NymdError {
|
||||
pretty_error: source.to_string(),
|
||||
source,
|
||||
}
|
||||
}
|
||||
}
|
||||
nymd_error => Self::NymdError {
|
||||
pretty_error: nymd_error.to_string(),
|
||||
source: nymd_error,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ValidatorClientError> for BackendError {
|
||||
fn from(e: ValidatorClientError) -> Self {
|
||||
match e {
|
||||
|
||||
Reference in New Issue
Block a user