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:
Jon Häggblad
2022-12-16 12:02:23 +01:00
committed by GitHub
parent 254302ec38
commit da094f0208
5 changed files with 85 additions and 19 deletions
@@ -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 {
+4
View File
@@ -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.
+31 -2
View File
@@ -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 {