1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use cosmrs::proto::cosmos::base::abci::v1beta1::Result;
use cosmrs::proto::prost::{DecodeError, EncodeError};
use cosmrs::tendermint::Hash;
use cosmrs::ErrorReport;
use tendermint_rpc::endpoint::abci_query::AbciQuery;
use thiserror::Error;

#[cfg(feature = "keyring")]
pub use keyring::Error as KeyringError;

pub use cosmrs::rpc::Error as TendermintRPCError;
pub use cosmrs::tendermint::Error as TendermintError;

#[derive(Error, Debug)]
pub enum ChainError {
    #[error("invalid denomination: {name:?}")]
    Denom { name: String },

    #[error("invalid chainId: {chain_id:?}")]
    ChainId { chain_id: String },

    #[error("api endpoint is not configured {api_type:?}")]
    MissingApiEndpoint { api_type: String },

    #[error("invalid mnemonic")]
    Mnemonic,

    #[error("invalid derivation path")]
    DerviationPath,

    #[error("cryptographic error: {message:?}")]
    Crypto { message: String },

    #[error("invalid query path url: {url:?}")]
    QueryPath { url: String },

    #[error("proto encoding error: {message:?}")]
    ProtoEncoding { message: String },

    #[error("proto decoding error: {message:?}")]
    ProtoDecoding { message: String },

    #[error("error during simulation: {result:?}")]
    Simulation { result: Result },

    #[error("tx_search timed out looking for: {tx_hash:?}")]
    TxSearchTimeout { tx_hash: Hash },

    #[error("tx_commit error: {res}")]
    TxCommit { res: String },

    #[error("tx_sync error: {res}")]
    TxSync { res: String },

    #[error("tx_async error: {res}")]
    TxAsync { res: String },

    #[cfg(feature = "keyring")]
    #[error(transparent)]
    Keyring(#[from] KeyringError),

    #[error("CosmosSDK error: {res:?}")]
    AbciQuery { res: AbciQuery },

    #[error("Tendermint error")]
    Tendermint(#[from] TendermintError),

    #[error(transparent)]
    RPC(#[from] TendermintRPCError),
}

impl ChainError {
    pub(crate) fn crypto(e: ErrorReport) -> ChainError {
        ChainError::Crypto {
            message: e.to_string(),
        }
    }

    pub(crate) fn proto_encoding(e: ErrorReport) -> ChainError {
        ChainError::ProtoEncoding {
            message: e.to_string(),
        }
    }

    pub(crate) fn prost_proto_encoding(e: EncodeError) -> ChainError {
        ChainError::ProtoEncoding {
            message: e.to_string(),
        }
    }

    pub(crate) fn prost_proto_decoding(e: DecodeError) -> ChainError {
        ChainError::ProtoDecoding {
            message: e.to_string(),
        }
    }
}

#[derive(Error, Debug)]
pub enum DeserializeError {
    #[error("Raw chain response is empty")]
    EmptyResponse,

    #[error(transparent)]
    Serde(#[from] serde_json::error::Error),
}