-
Notifications
You must be signed in to change notification settings - Fork 129
Expand file tree
/
Copy patherror.rs
More file actions
172 lines (160 loc) · 4.76 KB
/
Copy patherror.rs
File metadata and controls
172 lines (160 loc) · 4.76 KB
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
use std::num::ParseIntError;
use ain_db::DBError;
use anyhow::format_err;
use axum::{
http::StatusCode,
response::{IntoResponse, Response},
Json,
};
use bitcoin::hex::HexToArrayError;
use serde::Serialize;
use serde_json::json;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum NotFoundKind {
#[error("proposal")]
Proposal,
#[error("masternode")]
Masternode,
#[error("scheme")]
Scheme,
#[error("oracle")]
Oracle,
#[error("token")]
Token,
#[error("poolpair")]
PoolPair,
#[error("rawtx")]
RawTx,
}
#[derive(Error, Debug)]
pub enum Error {
#[error("Ocean: Bincode error: {0:?}")]
BincodeError(#[from] bincode::Error),
#[error("Ocean: HexToArrayError error: {0:?}")]
HexToArrayError(#[from] HexToArrayError),
#[error("Ocean: ParseIntError error: {0:?}")]
ParseIntError(#[from] ParseIntError),
#[error("Ocean: DBError error: {0:?}")]
DBError(#[from] DBError),
#[error("Ocean: IO error: {0:?}")]
IOError(#[from] std::io::Error),
#[error("Ocean: FromHexError error: {0:?}")]
FromHexError(#[from] hex::FromHexError),
#[error("Ocean: Consensus encode error: {0:?}")]
ConsensusEncodeError(#[from] bitcoin::consensus::encode::Error),
#[error("Ocean: jsonrpsee error: {0:?}")]
JsonrpseeError(#[from] jsonrpsee::core::Error),
#[error("Ocean: serde_json error: {0:?}")]
SerdeJSONError(#[from] serde_json::Error),
#[error("Ocean: RPC error: {0:?}")]
RpcError(#[from] defichain_rpc::Error),
#[error("Unable to find {0:}")]
NotFound(NotFoundKind),
#[error("Ocean: Decimal error: {0:?}")]
DecimalError(#[from] rust_decimal::Error),
#[error("Decimal conversion error")]
DecimalConversionError,
#[error("Ocean: Overflow error")]
OverflowError,
#[error("Ocean: Underflow error")]
UnderflowError,
#[error("Error fetching primary value")]
SecondaryIndex,
#[error("Token {0:?} is invalid as it is not tradeable")]
UntradeableTokenError(String),
#[error("Ocean: BitcoinAddressError: {0:?}")]
BitcoinAddressError(#[from] bitcoin::address::Error),
#[error("Ocean: TryFromIntError: {0:?}")]
TryFromIntError(#[from] std::num::TryFromIntError),
#[error(transparent)]
Other(#[from] anyhow::Error),
#[error("Validation error: {0}")]
ValidationError(String),
#[error("{0}")]
BadRequest(String),
}
#[derive(Serialize)]
pub enum ErrorKind {
NotFound,
BadRequest,
Unknown,
}
#[derive(Serialize)]
struct ApiErrorData {
code: u16,
r#type: ErrorKind,
at: u128,
message: String,
url: String,
}
#[derive(Serialize)]
pub struct ApiError {
error: ApiErrorData,
#[serde(skip)]
status: StatusCode,
}
impl ApiError {
pub fn new(status: StatusCode, message: String, url: String) -> Self {
let current_time = std::time::SystemTime::now();
let at = current_time
.duration_since(std::time::UNIX_EPOCH)
.expect("Time went backwards")
.as_millis();
let r#type = match status {
StatusCode::NOT_FOUND => ErrorKind::NotFound,
StatusCode::BAD_REQUEST => ErrorKind::BadRequest,
_ => ErrorKind::Unknown,
};
Self {
error: ApiErrorData {
r#type,
code: status.as_u16(),
message,
url,
at,
},
status,
}
}
}
impl IntoResponse for ApiError {
fn into_response(self) -> Response {
let status = self.status;
let body = Json(json!({
"error": self.error
}));
(status, body).into_response()
}
}
impl Error {
pub fn into_code_and_message(self) -> (StatusCode, String) {
let (code, reason) = match &self {
Error::RpcError(defichain_rpc::Error::JsonRpc(jsonrpc_async::error::Error::Rpc(e))) => {
(
StatusCode::NOT_FOUND,
match e {
e if e.message.contains("Cannot find existing loan scheme") => {
format!("{}", Error::NotFound(NotFoundKind::Scheme))
}
_ => e.message.to_string(),
},
)
}
Error::NotFound(_) => (StatusCode::NOT_FOUND, format!("{self}")),
Error::BadRequest(msg) => (StatusCode::BAD_REQUEST, msg.clone()),
_ => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()),
};
(code, reason)
}
}
impl From<Box<dyn std::error::Error>> for Error {
fn from(err: Box<dyn std::error::Error>) -> Error {
Error::Other(format_err!("{err}"))
}
}
impl From<&str> for Error {
fn from(s: &str) -> Self {
Error::Other(format_err!("{s}"))
}
}