tendermint_rpc/
response_error.rs1use core::fmt::Display;
2
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4
5use crate::prelude::*;
6
7#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
8pub struct ResponseError {
9 code: Code,
11
12 message: String,
14
15 data: Option<String>,
17}
18
19#[derive(Copy, Clone, Debug, Eq, thiserror::Error, Hash, PartialEq, PartialOrd, Ord)]
24pub enum Code {
25 #[error("HTTP error")]
27 HttpError,
28
29 #[error("WebSocket Error")]
31 WebSocketError,
32
33 #[error("Client internal error")]
40 ClientInternalError,
41
42 #[error("Parse error. Invalid JSON")]
44 ParseError,
45
46 #[error("Invalid Request")]
48 InvalidRequest,
49
50 #[error("Method not found")]
52 MethodNotFound,
53
54 #[error("Invalid params")]
56 InvalidParams,
57
58 #[error("Internal error")]
60 InternalError,
61
62 #[error("Server error")]
64 ServerError,
65
66 #[error("Error (code: {})", 0)]
68 Other(i32),
69}
70
71impl Code {
72 pub fn value(self) -> i32 {
74 i32::from(self)
75 }
76}
77
78impl From<i32> for Code {
79 fn from(value: i32) -> Code {
80 match value {
81 0 => Code::HttpError,
82 1 => Code::WebSocketError,
83 2 => Code::ClientInternalError,
84 -32700 => Code::ParseError,
85 -32600 => Code::InvalidRequest,
86 -32601 => Code::MethodNotFound,
87 -32602 => Code::InvalidParams,
88 -32603 => Code::InternalError,
89 -32000 => Code::ServerError,
90 other => Code::Other(other),
91 }
92 }
93}
94
95impl From<Code> for i32 {
96 fn from(code: Code) -> i32 {
97 match code {
98 Code::HttpError => 0,
99 Code::WebSocketError => 1,
100 Code::ClientInternalError => 2,
101 Code::ParseError => -32700,
102 Code::InvalidRequest => -32600,
103 Code::MethodNotFound => -32601,
104 Code::InvalidParams => -32602,
105 Code::InternalError => -32603,
106 Code::ServerError => -32000,
107 Code::Other(other) => other,
108 }
109 }
110}
111
112impl Display for ResponseError {
113 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
114 match &self.data {
115 Some(data) => write!(
116 f,
117 "{}: {} (code: {})",
118 self.message,
119 data,
120 self.code.value()
121 ),
122 None => write!(f, "{} (code: {})", self.message, self.code.value()),
123 }
124 }
125}
126
127impl ResponseError {
128 pub fn new(code: Code, data: Option<String>) -> ResponseError {
130 let message = code.to_string();
131
132 ResponseError {
133 code,
134 message,
135 data,
136 }
137 }
138
139 pub fn http_error(message: impl Into<String>) -> ResponseError {
141 ResponseError {
142 code: Code::HttpError,
143 message: message.into(),
144 data: None,
145 }
146 }
147
148 pub fn invalid_params(data: &str) -> ResponseError {
150 ResponseError::new(Code::InvalidParams, Some(data.to_string()))
151 }
152
153 pub fn websocket_error(cause: impl Into<String>) -> ResponseError {
155 ResponseError::new(Code::WebSocketError, Some(cause.into()))
156 }
157
158 pub fn method_not_found(name: &str) -> ResponseError {
160 ResponseError::new(Code::MethodNotFound, Some(name.to_string()))
161 }
162
163 pub fn parse_error<E>(error: E) -> ResponseError
165 where
166 E: Display,
167 {
168 ResponseError::new(Code::ParseError, Some(error.to_string()))
169 }
170
171 pub fn server_error<D>(data: D) -> ResponseError
173 where
174 D: Display,
175 {
176 ResponseError::new(Code::ServerError, Some(data.to_string()))
177 }
178
179 pub fn client_internal_error(cause: impl Into<String>) -> ResponseError {
181 ResponseError::new(Code::ClientInternalError, Some(cause.into()))
182 }
183
184 pub fn code(&self) -> Code {
186 self.code
187 }
188
189 pub fn message(&self) -> &str {
191 &self.message
192 }
193
194 pub fn data(&self) -> Option<&str> {
196 self.data.as_ref().map(AsRef::as_ref)
197 }
198}
199
200impl<'de> Deserialize<'de> for Code {
201 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
202 Ok(Code::from(i32::deserialize(deserializer)?))
203 }
204}
205
206impl Serialize for Code {
207 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
208 self.value().serialize(serializer)
209 }
210}