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
use alloc::string::{String, ToString};
use core::fmt;

use miden_objects::{accounts::AccountId, utils::DeserializationError, NoteError};

// RPC ERROR
// ================================================================================================

#[derive(Debug)]
pub enum RpcError {
    ConnectionError(String),
    DeserializationError(String),
    ExpectedFieldMissing(String),
    AccountUpdateForPrivateAccountReceived(AccountId),
    RequestError(String, String),
}

impl fmt::Display for RpcError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            RpcError::ConnectionError(err) => {
                write!(f, "failed to connect to the API server: {err}")
            },
            RpcError::DeserializationError(err) => {
                write!(f, "failed to deserialize RPC data: {err}")
            },
            RpcError::ExpectedFieldMissing(err) => {
                write!(f, "rpc API response missing an expected field: {err}")
            },
            RpcError::AccountUpdateForPrivateAccountReceived(account_id) => {
                write!(
                    f,
                    "rpc API response contained an update for a private account: {}",
                    account_id.to_hex()
                )
            },
            RpcError::RequestError(endpoint, err) => {
                write!(f, "rpc request failed for {endpoint}: {err}")
            },
        }
    }
}

impl From<DeserializationError> for RpcError {
    fn from(err: DeserializationError) -> Self {
        Self::DeserializationError(err.to_string())
    }
}

impl From<NoteError> for RpcError {
    fn from(err: NoteError) -> Self {
        Self::DeserializationError(err.to_string())
    }
}

impl From<RpcConversionError> for RpcError {
    fn from(err: RpcConversionError) -> Self {
        Self::DeserializationError(err.to_string())
    }
}

// RPC CONVERSION ERROR
// ================================================================================================

#[derive(Debug, Clone, PartialEq)]
pub enum RpcConversionError {
    NotAValidFelt,
    NoteTypeError(NoteError),
    MissingFieldInProtobufRepresentation {
        entity: &'static str,
        field_name: &'static str,
    },
}

impl core::fmt::Display for RpcConversionError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            RpcConversionError::NotAValidFelt => write!(f, "Value is not in the range 0..MODULUS"),
            RpcConversionError::NoteTypeError(err) => write!(f, "Invalid note type value: {}", err),
            RpcConversionError::MissingFieldInProtobufRepresentation { entity, field_name } => {
                write!(
                    f,
                    "Field `{}` required to be filled in protobuf representation of {}",
                    field_name, entity
                )
            },
        }
    }
}

impl Eq for RpcConversionError {}

impl From<NoteError> for RpcConversionError {
    fn from(error: NoteError) -> Self {
        RpcConversionError::NoteTypeError(error)
    }
}