corepc_client/client_sync/
error.rs

1// SPDX-License-Identifier: CC0-1.0
2
3use std::{error, fmt, io};
4
5use bitcoin::hex;
6
7/// The error type for errors produced in this library.
8#[derive(Debug)]
9pub enum Error {
10    JsonRpc(jsonrpc::error::Error),
11    HexToArray(hex::HexToArrayError),
12    HexToBytes(hex::HexToBytesError),
13    Json(serde_json::error::Error),
14    BitcoinSerialization(bitcoin::consensus::encode::FromHexError),
15    Io(io::Error),
16    InvalidCookieFile,
17    /// The JSON result had an unexpected structure.
18    UnexpectedStructure,
19    /// The daemon returned an error string.
20    Returned(String),
21    /// The server version did not match what was expected.
22    ServerVersion(UnexpectedServerVersionError),
23    /// Missing user/password
24    MissingUserPassword,
25}
26
27impl From<jsonrpc::error::Error> for Error {
28    fn from(e: jsonrpc::error::Error) -> Error { Error::JsonRpc(e) }
29}
30
31impl From<hex::HexToArrayError> for Error {
32    fn from(e: hex::HexToArrayError) -> Self { Self::HexToArray(e) }
33}
34
35impl From<hex::HexToBytesError> for Error {
36    fn from(e: hex::HexToBytesError) -> Self { Self::HexToBytes(e) }
37}
38
39impl From<serde_json::error::Error> for Error {
40    fn from(e: serde_json::error::Error) -> Error { Error::Json(e) }
41}
42
43impl From<bitcoin::consensus::encode::FromHexError> for Error {
44    fn from(e: bitcoin::consensus::encode::FromHexError) -> Error { Error::BitcoinSerialization(e) }
45}
46
47impl From<io::Error> for Error {
48    fn from(e: io::Error) -> Error { Error::Io(e) }
49}
50
51impl fmt::Display for Error {
52    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53        use Error::*;
54
55        match *self {
56            JsonRpc(ref e) => write!(f, "JSON-RPC error: {}", e),
57            HexToArray(ref e) => write!(f, "hex to array decode error: {}", e),
58            HexToBytes(ref e) => write!(f, "hex to bytes decode error: {}", e),
59            Json(ref e) => write!(f, "JSON error: {}", e),
60            BitcoinSerialization(ref e) => write!(f, "Bitcoin serialization error: {}", e),
61            Io(ref e) => write!(f, "I/O error: {}", e),
62            InvalidCookieFile => write!(f, "invalid cookie file"),
63            UnexpectedStructure => write!(f, "the JSON result had an unexpected structure"),
64            Returned(ref s) => write!(f, "the daemon returned an error string: {}", s),
65            ServerVersion(ref e) => write!(f, "server version: {}", e),
66            MissingUserPassword => write!(f, "missing user and/or password"),
67        }
68    }
69}
70
71impl error::Error for Error {
72    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
73        use Error::*;
74
75        match *self {
76            JsonRpc(ref e) => Some(e),
77            HexToArray(ref e) => Some(e),
78            HexToBytes(ref e) => Some(e),
79            Json(ref e) => Some(e),
80            BitcoinSerialization(ref e) => Some(e),
81            Io(ref e) => Some(e),
82            ServerVersion(ref e) => Some(e),
83            InvalidCookieFile | UnexpectedStructure | Returned(_) | MissingUserPassword => None,
84        }
85    }
86}
87
88/// Error returned when RPC client expects a different version than bitcoind reports.
89#[derive(Debug, Clone, PartialEq, Eq)]
90pub struct UnexpectedServerVersionError {
91    /// Version from server.
92    pub got: usize,
93    /// Expected server version.
94    pub expected: Vec<usize>,
95}
96
97impl fmt::Display for UnexpectedServerVersionError {
98    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
99        let mut expected = String::new();
100        for version in &self.expected {
101            let v = format!(" {} ", version);
102            expected.push_str(&v);
103        }
104        write!(f, "unexpected bitcoind version, got: {} expected one of: {}", self.got, expected)
105    }
106}
107
108impl error::Error for UnexpectedServerVersionError {}
109
110impl From<UnexpectedServerVersionError> for Error {
111    fn from(e: UnexpectedServerVersionError) -> Self { Self::ServerVersion(e) }
112}