1#![allow(unused)]
2
3#[macro_use]
4extern crate log;
5
6use int_enum::IntEnum;
7use serde::de::{self, Visitor};
8use serde::{Deserialize, Deserializer, Serialize, Serializer};
9use std::error::Error;
10use std::fmt::{self, Debug, Display};
11use std::io::ErrorKind;
12pub const BUCKY_SYSTEM_ERROR_CODE_START: u16 = 0;
16pub const BUCKY_SYSTEM_ERROR_CODE_END: u16 = 5000;
17
18pub const BUCKY_META_ERROR_CODE_START: u16 = 5000;
21pub const BUCKY_META_ERROR_CODE_END: u16 = 6000;
22
23pub const BUCKY_META_ERROR_CODE_MAX: u16 =
24 BUCKY_META_ERROR_CODE_END - BUCKY_META_ERROR_CODE_START - 1;
25
26pub const BUCKY_DEC_ERROR_CODE_START: u16 = 15000;
29pub const BUCKY_DEC_ERROR_CODE_END: u16 = u16::MAX;
30
31pub const BUCKY_DEC_ERROR_CODE_MAX: u16 = BUCKY_DEC_ERROR_CODE_END - BUCKY_DEC_ERROR_CODE_START;
33
34pub fn is_system_error_code(code: u16) -> bool {
35 code < BUCKY_SYSTEM_ERROR_CODE_END
36}
37
38pub fn is_meta_error_code(code: u16) -> bool {
39 code >= BUCKY_META_ERROR_CODE_START && code < BUCKY_META_ERROR_CODE_END
40}
41
42pub fn is_dec_error_code(code: u16) -> bool {
43 code >= BUCKY_DEC_ERROR_CODE_START
44}
45
46#[repr(u16)]
48#[derive(
49Debug, Clone, Copy, Eq, IntEnum, PartialEq, Serialize, Deserialize,
50)]
51pub enum BuckySystemErrorCode {
52 Ok = 0,
53
54 Failed = 1,
55 InvalidParam = 2,
56 Timeout = 3,
57 NotFound = 4,
58 AlreadyExists = 5,
59 NotSupport = 6,
60 ErrorState = 7,
61 InvalidFormat = 8,
62 Expired = 9,
63 OutOfLimit = 10,
64 InternalError = 11,
65
66 PermissionDenied = 12,
67 ConnectionRefused = 13,
68 ConnectionReset = 14,
69 ConnectionAborted = 15,
70 NotConnected = 16,
71 AddrInUse = 18,
72 AddrNotAvailable = 19,
73 Interrupted = 20,
74 InvalidInput = 21,
75 InvalidData = 22,
76 WriteZero = 23,
77 UnexpectedEof = 24,
78 BrokenPipe = 25,
79 WouldBlock = 26,
80
81 UnSupport = 27,
82 Unmatch = 28,
83 ExecuteError = 29,
84 Reject = 30,
85 Ignored = 31,
86 InvalidSignature = 32,
87 AlreadyExistsAndSignatureMerged = 33,
88 TargetNotFound = 34,
89 Aborted = 35,
90
91 ConnectFailed = 40,
92 ConnectInterZoneFailed = 41,
93 InnerPathNotFound = 42,
94 RangeNotSatisfiable = 43,
95 UserCanceled = 44,
96 Conflict = 50,
97
98 OutofSessionLimit = 60,
99
100 Redirect = 66,
101
102 MongoDBError = 99,
103 SqliteError = 100,
104 UrlError = 101,
105 ZipError = 102,
106 HttpError = 103,
107 JsonError = 104,
108 HexError = 105,
109 RsaError = 106,
110 CryptoError = 107,
111 MpscSendError = 108,
112 MpscRecvError = 109,
113 IoError = 110,
114 NetworkError = 111,
115
116 CodeError = 250, UnknownBdtError = 253,
118 UnknownIOError = 254,
119 Unknown = 255,
120
121 Pending = 256,
122 NotChange = 257,
123
124 NotMatch = 258,
125 NotImplement = 259,
126 NotInit = 260,
127 ParseError = 261,
128 NotHandled = 262,
129
130 InvalidTarget = 263,
131 ErrorTimestamp = 264,
132 DecNotRunning = 265,
133
134 MetaError = 5000,
136
137 DecError = 15000,
139}
140
141impl Into<u16> for BuckySystemErrorCode {
142 fn into(self) -> u16 {
143 unsafe { std::mem::transmute(self as u16) }
144 }
145}
146
147impl From<u16> for BuckySystemErrorCode {
148 fn from(code: u16) -> Self {
149 match Self::from_int(code) {
150 Ok(code) => code,
151 Err(e) => {
152 error!("unknown system error code: {} {}", code, e);
153 if is_dec_error_code(code) {
154 Self::DecError
155 } else if is_meta_error_code(code) {
156 Self::MetaError
157 } else {
158 Self::Unknown
159 }
160 }
161 }
162 }
163}
164
165#[repr(u16)]
167#[derive(Debug, Clone, Copy, Eq, PartialEq)]
168pub enum BuckyErrorCode {
169 Ok,
170
171 Failed,
172 InvalidParam,
173 Timeout,
174 NotFound,
175 AlreadyExists,
176 NotSupport,
177 ErrorState,
178 InvalidFormat,
179 Expired,
180 OutOfLimit,
181 InternalError,
182
183 PermissionDenied,
184 ConnectionRefused,
185 ConnectionReset,
186 ConnectionAborted,
187 NotConnected,
188 AddrInUse,
189 AddrNotAvailable,
190 Interrupted,
191 InvalidInput,
192 InvalidData,
193 WriteZero,
194 UnexpectedEof,
195 BrokenPipe,
196 WouldBlock,
197
198 UnSupport,
199 Unmatch,
200 ExecuteError,
201 Reject,
202 Ignored,
203 InvalidSignature,
204 AlreadyExistsAndSignatureMerged,
205 TargetNotFound,
206 Aborted,
207
208 ConnectFailed,
209 ConnectInterZoneFailed,
210 InnerPathNotFound,
211 RangeNotSatisfiable,
212 UserCanceled,
213
214 Conflict,
215
216 OutofSessionLimit,
217
218 Redirect,
219
220 MongoDBError,
221 SqliteError,
222 UrlError,
223 ZipError,
224 HttpError,
225 JsonError,
226 HexError,
227 RsaError,
228 CryptoError,
229 MpscSendError,
230 MpscRecvError,
231 IoError,
232 NetworkError,
233
234 CodeError, UnknownBdtError,
236 UnknownIOError,
237 Unknown,
238
239 Pending,
240 NotChange,
241
242 NotMatch,
243 NotImplement,
244 NotInit,
245
246 ParseError,
247 NotHandled,
248
249 InvalidTarget,
250 ErrorTimestamp,
251 DecNotRunning,
252
253 MetaError(u16),
255
256 DecError(u16),
258}
259
260impl Into<BuckySystemErrorCode> for BuckyErrorCode {
261 fn into(self) -> BuckySystemErrorCode {
262 match self {
263 Self::Ok => BuckySystemErrorCode::Ok,
264
265 Self::Failed => BuckySystemErrorCode::Failed,
266 Self::InvalidParam => BuckySystemErrorCode::InvalidParam,
267 Self::Timeout => BuckySystemErrorCode::Timeout,
268 Self::NotFound => BuckySystemErrorCode::NotFound,
269 Self::AlreadyExists => BuckySystemErrorCode::AlreadyExists,
270 Self::NotSupport => BuckySystemErrorCode::NotSupport,
271 Self::ErrorState => BuckySystemErrorCode::ErrorState,
272 Self::InvalidFormat => BuckySystemErrorCode::InvalidFormat,
273 Self::Expired => BuckySystemErrorCode::Expired,
274 Self::OutOfLimit => BuckySystemErrorCode::OutOfLimit,
275 Self::InternalError => BuckySystemErrorCode::InternalError,
276
277 Self::PermissionDenied => BuckySystemErrorCode::PermissionDenied,
278 Self::ConnectionRefused => BuckySystemErrorCode::ConnectionRefused,
279 Self::ConnectionReset => BuckySystemErrorCode::ConnectionReset,
280 Self::ConnectionAborted => BuckySystemErrorCode::ConnectionAborted,
281 Self::NotConnected => BuckySystemErrorCode::NotConnected,
282 Self::AddrInUse => BuckySystemErrorCode::AddrInUse,
283 Self::AddrNotAvailable => BuckySystemErrorCode::AddrNotAvailable,
284 Self::Interrupted => BuckySystemErrorCode::Interrupted,
285 Self::InvalidInput => BuckySystemErrorCode::InvalidInput,
286 Self::InvalidData => BuckySystemErrorCode::InvalidData,
287 Self::WriteZero => BuckySystemErrorCode::WriteZero,
288 Self::UnexpectedEof => BuckySystemErrorCode::UnexpectedEof,
289 Self::BrokenPipe => BuckySystemErrorCode::BrokenPipe,
290 Self::WouldBlock => BuckySystemErrorCode::WouldBlock,
291
292 Self::UnSupport => BuckySystemErrorCode::UnSupport,
293 Self::Unmatch => BuckySystemErrorCode::Unmatch,
294 Self::ExecuteError => BuckySystemErrorCode::ExecuteError,
295 Self::Reject => BuckySystemErrorCode::Reject,
296 Self::Ignored => BuckySystemErrorCode::Ignored,
297 Self::InvalidSignature => BuckySystemErrorCode::InvalidSignature,
298 Self::AlreadyExistsAndSignatureMerged => {
299 BuckySystemErrorCode::AlreadyExistsAndSignatureMerged
300 }
301 Self::TargetNotFound => BuckySystemErrorCode::TargetNotFound,
302 Self::Aborted => BuckySystemErrorCode::Aborted,
303
304 Self::ConnectFailed => BuckySystemErrorCode::ConnectFailed,
305 Self::ConnectInterZoneFailed => BuckySystemErrorCode::ConnectInterZoneFailed,
306 Self::InnerPathNotFound => BuckySystemErrorCode::InnerPathNotFound,
307 Self::RangeNotSatisfiable => BuckySystemErrorCode::RangeNotSatisfiable,
308 Self::UserCanceled => BuckySystemErrorCode::UserCanceled,
309 Self::Conflict => BuckySystemErrorCode::Conflict,
310
311 Self::OutofSessionLimit => BuckySystemErrorCode::OutofSessionLimit,
312 Self::Redirect => BuckySystemErrorCode::Redirect,
313
314 Self::MongoDBError => BuckySystemErrorCode::MongoDBError,
315 Self::SqliteError => BuckySystemErrorCode::SqliteError,
316 Self::UrlError => BuckySystemErrorCode::UrlError,
317 Self::ZipError => BuckySystemErrorCode::ZipError,
318 Self::HttpError => BuckySystemErrorCode::HttpError,
319 Self::JsonError => BuckySystemErrorCode::JsonError,
320 Self::HexError => BuckySystemErrorCode::RsaError,
321 Self::RsaError => BuckySystemErrorCode::InternalError,
322 Self::CryptoError => BuckySystemErrorCode::CryptoError,
323 Self::MpscSendError => BuckySystemErrorCode::MpscSendError,
324 Self::MpscRecvError => BuckySystemErrorCode::MpscRecvError,
325 Self::IoError => BuckySystemErrorCode::IoError,
326 Self::NetworkError => BuckySystemErrorCode::NetworkError,
327
328 Self::CodeError => BuckySystemErrorCode::CodeError,
329 Self::UnknownBdtError => BuckySystemErrorCode::UnknownBdtError,
330 Self::UnknownIOError => BuckySystemErrorCode::UnknownIOError,
331 Self::Unknown => BuckySystemErrorCode::Unknown,
332
333 Self::Pending => BuckySystemErrorCode::Pending,
334 Self::NotChange => BuckySystemErrorCode::NotChange,
335
336 Self::NotMatch => BuckySystemErrorCode::NotMatch,
337 Self::NotImplement => BuckySystemErrorCode::NotImplement,
338 Self::NotInit => BuckySystemErrorCode::NotInit,
339
340 Self::ParseError => BuckySystemErrorCode::ParseError,
341 Self::NotHandled => BuckySystemErrorCode::NotHandled,
342
343 Self::InvalidTarget => BuckySystemErrorCode::InvalidTarget,
344 Self::ErrorTimestamp => BuckySystemErrorCode::ErrorTimestamp,
345 Self::DecNotRunning => BuckySystemErrorCode::DecNotRunning,
346
347 Self::MetaError(_) => BuckySystemErrorCode::MetaError,
348 Self::DecError(_) => BuckySystemErrorCode::DecError,
349 }
350 }
351}
352
353impl Into<BuckyErrorCode> for BuckySystemErrorCode {
354 fn into(self) -> BuckyErrorCode {
355 match self {
356 Self::Ok => BuckyErrorCode::Ok,
357
358 Self::Failed => BuckyErrorCode::Failed,
359 Self::InvalidParam => BuckyErrorCode::InvalidParam,
360 Self::Timeout => BuckyErrorCode::Timeout,
361 Self::NotFound => BuckyErrorCode::NotFound,
362 Self::AlreadyExists => BuckyErrorCode::AlreadyExists,
363 Self::NotSupport => BuckyErrorCode::NotSupport,
364 Self::ErrorState => BuckyErrorCode::ErrorState,
365 Self::InvalidFormat => BuckyErrorCode::InvalidFormat,
366 Self::Expired => BuckyErrorCode::Expired,
367 Self::OutOfLimit => BuckyErrorCode::OutOfLimit,
368 Self::InternalError => BuckyErrorCode::InternalError,
369
370 Self::PermissionDenied => BuckyErrorCode::PermissionDenied,
371 Self::ConnectionRefused => BuckyErrorCode::ConnectionRefused,
372 Self::ConnectionReset => BuckyErrorCode::ConnectionReset,
373 Self::ConnectionAborted => BuckyErrorCode::ConnectionAborted,
374 Self::NotConnected => BuckyErrorCode::NotConnected,
375 Self::AddrInUse => BuckyErrorCode::AddrInUse,
376 Self::AddrNotAvailable => BuckyErrorCode::AddrNotAvailable,
377 Self::Interrupted => BuckyErrorCode::Interrupted,
378 Self::InvalidInput => BuckyErrorCode::InvalidInput,
379 Self::InvalidData => BuckyErrorCode::InvalidData,
380 Self::WriteZero => BuckyErrorCode::WriteZero,
381 Self::UnexpectedEof => BuckyErrorCode::UnexpectedEof,
382 Self::BrokenPipe => BuckyErrorCode::BrokenPipe,
383 Self::WouldBlock => BuckyErrorCode::WouldBlock,
384
385 Self::UnSupport => BuckyErrorCode::UnSupport,
386 Self::Unmatch => BuckyErrorCode::Unmatch,
387 Self::ExecuteError => BuckyErrorCode::ExecuteError,
388 Self::Reject => BuckyErrorCode::Reject,
389 Self::Ignored => BuckyErrorCode::Ignored,
390 Self::InvalidSignature => BuckyErrorCode::InvalidSignature,
391 Self::AlreadyExistsAndSignatureMerged => {
392 BuckyErrorCode::AlreadyExistsAndSignatureMerged
393 }
394 Self::TargetNotFound => BuckyErrorCode::TargetNotFound,
395 Self::Aborted => BuckyErrorCode::Aborted,
396
397 Self::ConnectFailed => BuckyErrorCode::ConnectFailed,
398 Self::ConnectInterZoneFailed => BuckyErrorCode::ConnectInterZoneFailed,
399 Self::InnerPathNotFound => BuckyErrorCode::InnerPathNotFound,
400 Self::RangeNotSatisfiable => BuckyErrorCode::RangeNotSatisfiable,
401 Self::UserCanceled => BuckyErrorCode::UserCanceled,
402
403 Self::Conflict => BuckyErrorCode::Conflict,
404
405 Self::OutofSessionLimit => BuckyErrorCode::OutofSessionLimit,
406
407 Self::Redirect => BuckyErrorCode::Redirect,
408
409 Self::MongoDBError => BuckyErrorCode::MongoDBError,
410 Self::SqliteError => BuckyErrorCode::SqliteError,
411 Self::UrlError => BuckyErrorCode::UrlError,
412 Self::ZipError => BuckyErrorCode::ZipError,
413 Self::HttpError => BuckyErrorCode::HttpError,
414 Self::JsonError => BuckyErrorCode::JsonError,
415 Self::HexError => BuckyErrorCode::RsaError,
416 Self::RsaError => BuckyErrorCode::InternalError,
417 Self::CryptoError => BuckyErrorCode::CryptoError,
418 Self::MpscSendError => BuckyErrorCode::MpscSendError,
419 Self::MpscRecvError => BuckyErrorCode::MpscRecvError,
420 Self::IoError => BuckyErrorCode::IoError,
421 Self::NetworkError => BuckyErrorCode::NetworkError,
422
423 Self::CodeError => BuckyErrorCode::CodeError,
424 Self::UnknownBdtError => BuckyErrorCode::UnknownBdtError,
425 Self::UnknownIOError => BuckyErrorCode::UnknownIOError,
426 Self::Unknown => BuckyErrorCode::Unknown,
427
428 Self::Pending => BuckyErrorCode::Pending,
429 Self::NotChange => BuckyErrorCode::NotChange,
430
431 Self::NotMatch => BuckyErrorCode::NotMatch,
432 Self::NotImplement => BuckyErrorCode::NotImplement,
433 Self::NotInit => BuckyErrorCode::NotInit,
434
435 Self::ParseError => BuckyErrorCode::ParseError,
436 Self::NotHandled => BuckyErrorCode::NotHandled,
437
438 Self::InvalidTarget => BuckyErrorCode::InvalidTarget,
439 Self::ErrorTimestamp => BuckyErrorCode::ErrorTimestamp,
440 Self::DecNotRunning => BuckyErrorCode::DecNotRunning,
441
442 Self::MetaError => BuckyErrorCode::MetaError(0),
443 Self::DecError => BuckyErrorCode::DecError(0),
444 }
445 }
446}
447
448impl Into<u32> for BuckyErrorCode {
449 fn into(self) -> u32 {
450 let v: u16 = self.into();
451 v as u32
452 }
453}
454
455impl Into<i32> for BuckyErrorCode {
456 fn into(self) -> i32 {
457 let v: u16 = self.into();
458 v as i32
459 }
460}
461
462impl Into<u16> for BuckyErrorCode {
463 fn into(self) -> u16 {
464 match self {
465 Self::MetaError(mut v) => {
466 if v > BUCKY_META_ERROR_CODE_MAX {
467 error!("meta error code out of limit: {}", v);
468 v = BUCKY_META_ERROR_CODE_MAX;
469 }
470
471 BUCKY_META_ERROR_CODE_START + v
472 }
473 Self::DecError(mut v) => {
474 if v > BUCKY_DEC_ERROR_CODE_MAX {
475 error!("dec error code out of limit: {}", v);
476 v = BUCKY_DEC_ERROR_CODE_MAX;
477 }
478
479 BUCKY_DEC_ERROR_CODE_START + v
480 }
481 _ => Into::<BuckySystemErrorCode>::into(self).into(),
482 }
483 }
484}
485
486impl From<u16> for BuckyErrorCode {
487 fn from(code: u16) -> Self {
488 if is_system_error_code(code) {
489 BuckySystemErrorCode::from(code).into()
490 } else if is_meta_error_code(code) {
491 let code = code - BUCKY_META_ERROR_CODE_START;
492 Self::MetaError(code)
493 } else if is_dec_error_code(code) {
494 let code = code - BUCKY_DEC_ERROR_CODE_START;
495 Self::DecError(code)
496 } else {
497 error!("unknown error code: {}", code);
498 Self::Unknown
499 }
500 }
501}
502
503impl From<u32> for BuckyErrorCode {
504 fn from(code: u32) -> Self {
505 if code < u16::MAX as u32 {
506 Self::from(code as u16)
507 } else {
508 error!("u32 error code out of u16 limit: {}", code);
509 Self::Unknown
510 }
511 }
512}
513
514impl Display for BuckyErrorCode {
515 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
516 write!(f, "{}", self.as_u16())
517 }
518}
519
520impl Serialize for BuckyErrorCode {
521 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
522 where
523 S: Serializer,
524 {
525 serializer.serialize_u16(self.as_u16())
526 }
527}
528
529struct BuckyErrorCodeVisitor {}
530impl<'de> Visitor<'de> for BuckyErrorCodeVisitor {
531 type Value = BuckyErrorCode;
532
533 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
534 formatter.write_str("u16")
535 }
536
537 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
538 where
539 E: de::Error,
540 {
541 if v < u16::MAX as u64 {
542 Ok(BuckyErrorCode::from(v as u16))
543 } else {
544 error!("invalid BuckyErrorCode int value: {}", v);
545 Ok(BuckyErrorCode::Unknown)
546 }
547 }
548}
549
550impl<'de> Deserialize<'de> for BuckyErrorCode {
551 fn deserialize<D>(deserializer: D) -> Result<BuckyErrorCode, D::Error>
552 where
553 D: Deserializer<'de>,
554 {
555 deserializer.deserialize_u16(BuckyErrorCodeVisitor {})
556 }
557}
558
559impl BuckyErrorCode {
560 pub fn as_u8(&self) -> u8 {
561 let v: u16 = self.clone().into();
562 v as u8
563 }
564
565 pub fn into_u8(self) -> u8 {
566 let v: u16 = self.into();
567 v as u8
568 }
569
570 pub fn as_u16(&self) -> u16 {
571 self.clone().into()
572 }
573
574 pub fn into_u16(self) -> u16 {
575 self.into()
576 }
577
578 pub fn is_meta_error(&self) -> bool {
580 match *self {
581 Self::MetaError(_) => true,
582 _ => false,
583 }
584 }
585
586 pub fn is_dec_error(&self) -> bool {
588 match *self {
589 Self::DecError(_) => true,
590 _ => false,
591 }
592 }
593}
594
595pub enum BuckyErrorCodeEx {
597 System(BuckySystemErrorCode),
598 MetaError(u16),
599 DecError(u16),
600}
601
602impl Into<BuckyErrorCode> for BuckyErrorCodeEx {
603 fn into(self) -> BuckyErrorCode {
604 match self {
605 Self::System(code) => code.into(),
606 Self::MetaError(v) => BuckyErrorCode::MetaError(v),
607 Self::DecError(v) => BuckyErrorCode::DecError(v),
608 }
609 }
610}
611
612impl Into<BuckyErrorCodeEx> for BuckyErrorCode {
613 fn into(self) -> BuckyErrorCodeEx {
614 match self {
615 Self::MetaError(v) => BuckyErrorCodeEx::MetaError(v),
616 Self::DecError(v) => BuckyErrorCodeEx::DecError(v),
617 _ => self.into(),
618 }
619 }
620}
621
622impl Into<BuckyErrorCodeEx> for BuckySystemErrorCode {
623 fn into(self) -> BuckyErrorCodeEx {
624 BuckyErrorCodeEx::System(self)
625 }
626}
627
628#[derive(Debug)]
630pub enum BuckyOriginError {
631 IoError(std::io::Error),
632 SerdeJsonError(serde_json::error::Error),
633 #[cfg(feature = "http-types")]
634 HttpError(http_types::Error),
635 #[cfg(feature = "url")]
636 UrlError(url::ParseError),
637 #[cfg(feature = "zip")]
638 #[cfg(not(target_arch = "wasm32"))]
639 ZipError(zip::result::ZipError),
640 #[cfg(feature = "http-types")]
641 HttpStatusCodeError(http_types::StatusCode),
642 #[cfg(feature = "rusqlite")]
643 #[cfg(not(target_arch = "wasm32"))]
644 SqliteError(rusqlite::Error),
645 #[cfg(feature = "sqlx")]
646 SqlxError(sqlx::Error),
647 #[cfg(feature = "hex")]
648 HexError(hex::FromHexError),
649 #[cfg(feature = "rsa")]
650 RsaError(rsa::errors::Error),
651 CodeError(u32),
652 ParseIntError(std::num::ParseIntError),
653 ParseFloatError(std::num::ParseFloatError),
654 AddrParseError(std::net::AddrParseError),
655 StripPrefixError(std::path::StripPrefixError),
656 ParseUtf8Error(std::str::Utf8Error),
657 ErrorMsg(String),
658}
659
660pub struct BuckyError {
873 code: BuckyErrorCode,
874 msg: String,
875
876 origin: Option<BuckyOriginError>,
877}
878
879pub type BuckyResult<T> = Result<T, BuckyError>;
880
881impl Clone for BuckyError {
884 fn clone(&self) -> Self {
885 BuckyError::new(self.code(), self.msg())
886 }
887}
888
889impl BuckyError {
890 pub fn new(code: impl Into<BuckyErrorCode>, msg: impl Into<String>) -> Self {
891 Self {
892 code: code.into(),
893 msg: msg.into(),
894 origin: None,
895 }
896 }
897
898 pub fn set_code(&mut self, code: impl Into<BuckyErrorCode>) {
899 self.code = code.into();
900 }
901
902 pub fn code(&self) -> BuckyErrorCode {
903 self.code
904 }
905
906 pub fn with_code(mut self, code: impl Into<BuckyErrorCode>) -> Self {
907 self.code = code.into();
908 self
909 }
910
911 pub fn set_msg(&mut self, msg: impl Into<String>) {
912 self.msg = msg.into();
913 }
914
915 pub fn msg(&self) -> &str {
916 self.msg.as_ref()
917 }
918
919 pub fn with_msg(mut self, msg: impl Into<String>) -> Self {
920 self.msg = msg.into();
921 self
922 }
923
924 pub fn origin(&self) -> &Option<BuckyOriginError> {
925 &self.origin
926 }
927
928 pub fn into_origin(self) -> Option<BuckyOriginError> {
929 self.origin
930 }
931
932 fn format(&self) -> String {
933 format!("err: ({:?}, {}, {:?})", self.code, self.msg, self.origin)
934 }
935
936 pub fn error_with_log<T>(msg: impl Into<String> + std::fmt::Display) -> BuckyResult<T> {
937 error!("{}", msg);
938
939 Err(BuckyError::new(BuckyErrorCode::Failed, msg))
940 }
941}
942
943impl Error for BuckyError {}
944
945impl Display for BuckyError {
946 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
947 Display::fmt(&self.format(), f)
948 }
949}
950
951impl Debug for BuckyError {
952 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
953 Debug::fmt(&self.format(), f)
954 }
955}
956
957impl BuckyError {
958 fn io_error_kind_to_code(kind: std::io::ErrorKind) -> BuckyErrorCode {
959 match kind {
960 ErrorKind::NotFound => BuckyErrorCode::NotFound,
961 ErrorKind::PermissionDenied => BuckyErrorCode::PermissionDenied,
962 ErrorKind::ConnectionRefused => BuckyErrorCode::ConnectionRefused,
963 ErrorKind::ConnectionReset => BuckyErrorCode::ConnectionReset,
964 ErrorKind::ConnectionAborted => BuckyErrorCode::ConnectionAborted,
965 ErrorKind::NotConnected => BuckyErrorCode::NotConnected,
966 ErrorKind::AddrInUse => BuckyErrorCode::AddrInUse,
967 ErrorKind::AddrNotAvailable => BuckyErrorCode::AddrNotAvailable,
968 ErrorKind::BrokenPipe => BuckyErrorCode::BrokenPipe,
969 ErrorKind::AlreadyExists => BuckyErrorCode::AlreadyExists,
970 ErrorKind::WouldBlock => BuckyErrorCode::WouldBlock,
971 ErrorKind::InvalidInput => BuckyErrorCode::InvalidInput,
972 ErrorKind::InvalidData => BuckyErrorCode::InvalidData,
973 ErrorKind::TimedOut => BuckyErrorCode::Timeout,
974 ErrorKind::WriteZero => BuckyErrorCode::WriteZero,
975 ErrorKind::Interrupted => BuckyErrorCode::Interrupted,
976 ErrorKind::UnexpectedEof => BuckyErrorCode::UnexpectedEof,
977 _ => BuckyErrorCode::UnknownIOError,
978 }
979 }
980
981 fn convert_bdt_error_code(code: u32) -> BuckyErrorCode {
988 match code {
989 _ => BuckyErrorCode::UnknownBdtError,
990 }
991 }
992
993 fn bucky_error_to_io_error(e: BuckyError) -> std::io::Error {
994 std::io::Error::new(std::io::ErrorKind::Other, e)
995 }
996
997 fn io_error_to_bucky_error(e: std::io::Error) -> BuckyError {
998 let kind = e.kind();
999 if kind == std::io::ErrorKind::Other && e.get_ref().is_some() {
1000 match e.into_inner().unwrap().downcast::<BuckyError>() {
1001 Ok(e) => {
1002 e.as_ref().clone()
1003 }
1004 Err(e) => {
1005 BuckyError {
1006 code: Self::io_error_kind_to_code(kind),
1007 msg: format!("io_error: {}", e),
1008 origin: None,
1009 }
1010 }
1011 }
1012 } else {
1013 BuckyError {
1014 code: Self::io_error_kind_to_code(e.kind()),
1015 msg: format!("io_error: {}", e),
1016 origin: Some(BuckyOriginError::IoError(e)),
1017 }
1018 }
1019 }
1020}
1021
1022impl From<std::io::Error> for BuckyError {
1023 fn from(err: std::io::Error) -> BuckyError {
1024 BuckyError::io_error_to_bucky_error(err)
1025 }
1026}
1027
1028impl From<BuckyError> for std::io::Error {
1029 fn from(err: BuckyError) -> std::io::Error {
1030 BuckyError::bucky_error_to_io_error(err)
1031 }
1032}
1033
1034impl From<std::str::Utf8Error> for BuckyError {
1035 fn from(err: std::str::Utf8Error) -> BuckyError {
1036 BuckyError {
1037 code: BuckyErrorCode::InvalidFormat,
1038 msg: format!("io_error: {}", err),
1039 origin: Some(BuckyOriginError::ParseUtf8Error(err)),
1040 }
1041 }
1042}
1043
1044#[cfg(feature = "http-types")]
1045impl From<http_types::Error> for BuckyError {
1046 fn from(err: http_types::Error) -> BuckyError {
1047 BuckyError {
1048 code: BuckyErrorCode::HttpError,
1049 msg: format!("http_error: {}", err),
1050 origin: Some(BuckyOriginError::HttpError(err)),
1051 }
1052 }
1053}
1054
1055impl From<std::num::ParseIntError> for BuckyError {
1056 fn from(err: std::num::ParseIntError) -> BuckyError {
1057 BuckyError {
1058 code: BuckyErrorCode::InvalidFormat,
1059 msg: format!("parse_int_error: {}", err),
1060 origin: Some(BuckyOriginError::ParseIntError(err)),
1061 }
1062 }
1063}
1064
1065impl From<std::num::ParseFloatError> for BuckyError {
1066 fn from(err: std::num::ParseFloatError) -> BuckyError {
1067 BuckyError {
1068 code: BuckyErrorCode::InvalidFormat,
1069 msg: format!("parse_int_error: {}", err),
1070 origin: Some(BuckyOriginError::ParseFloatError(err)),
1071 }
1072 }
1073}
1074
1075impl From<std::net::AddrParseError> for BuckyError {
1076 fn from(err: std::net::AddrParseError) -> BuckyError {
1077 BuckyError {
1078 code: BuckyErrorCode::InvalidFormat,
1079 msg: format!("parse_int_error: {}", err),
1080 origin: Some(BuckyOriginError::AddrParseError(err)),
1081 }
1082 }
1083}
1084
1085impl From<std::path::StripPrefixError> for BuckyError {
1086 fn from(err: std::path::StripPrefixError) -> BuckyError {
1087 BuckyError {
1088 code: BuckyErrorCode::InvalidFormat,
1089 msg: format!("strip_prefix_error: {}", err),
1090 origin: Some(BuckyOriginError::StripPrefixError(err)),
1091 }
1092 }
1093}
1094
1095#[cfg(feature = "async-std")]
1096impl From<async_std::future::TimeoutError> for BuckyError {
1097 fn from(err: async_std::future::TimeoutError) -> BuckyError {
1098 BuckyError::new(BuckyErrorCode::Timeout, format!("{}", err))
1099 }
1100}
1101
1102impl From<u32> for BuckyError {
1103 fn from(err: u32) -> BuckyError {
1104 BuckyError {
1105 code: BuckyErrorCode::CodeError,
1106 msg: format!("base_code_error: {}", err),
1107 origin: Some(BuckyOriginError::CodeError(err)),
1108 }
1109 }
1110}
1111
1112pub struct CodeError(pub u32, pub String);
1113
1114impl From<CodeError> for BuckyError {
1115 fn from(err: CodeError) -> Self {
1116 BuckyError {
1117 code: BuckyErrorCode::CodeError,
1118 msg: err.1,
1119 origin: Some(BuckyOriginError::CodeError(err.0)),
1120 }
1121 }
1122}
1123
1124#[cfg(feature = "rusqlite")]
1125#[cfg(not(target_arch = "wasm32"))]
1126impl From<rusqlite::Error> for BuckyError {
1127 fn from(err: rusqlite::Error) -> BuckyError {
1128 BuckyError {
1129 code: BuckyErrorCode::SqliteError,
1130 msg: format!("sqlite_error: {}", err),
1131 origin: Some(BuckyOriginError::SqliteError(err)),
1132 }
1133 }
1134}
1135#[cfg(feature = "sqlx")]
1136impl From<sqlx::Error> for BuckyError {
1137 fn from(err: sqlx::Error) -> Self {
1138 Self {
1139 code: BuckyErrorCode::SqliteError,
1140 msg: format!("sqlx error: {}", err),
1141 origin: Some(BuckyOriginError::SqlxError(err))
1142 }
1143 }
1144}
1145
1146impl From<serde_json::error::Error> for BuckyError {
1147 fn from(e: serde_json::error::Error) -> Self {
1148 BuckyError {
1149 code: BuckyErrorCode::JsonError,
1150 msg: format!("json_error: {}", e),
1151 origin: Some(BuckyOriginError::SerdeJsonError(e)),
1152 }
1153 }
1154}
1155
1156#[cfg(feature = "http-types")]
1157impl From<http_types::StatusCode> for BuckyError {
1158 fn from(code: http_types::StatusCode) -> Self {
1159 BuckyError {
1160 code: BuckyErrorCode::HttpError,
1161 msg: format!("http status code: {}", code),
1162 origin: Some(BuckyOriginError::HttpStatusCodeError(code)),
1163 }
1164 }
1165}
1166
1167#[cfg(feature = "url")]
1168impl From<url::ParseError> for BuckyError {
1169 fn from(e: url::ParseError) -> Self {
1170 BuckyError {
1171 code: BuckyErrorCode::UrlError,
1172 msg: format!("url_error: {}", e),
1173 origin: Some(BuckyOriginError::UrlError(e)),
1174 }
1175 }
1176}
1177
1178#[cfg(feature = "zip")]
1179#[cfg(not(target_arch = "wasm32"))]
1180impl From<zip::result::ZipError> for BuckyError {
1181 fn from(e: zip::result::ZipError) -> Self {
1182 BuckyError {
1183 code: BuckyErrorCode::ZipError,
1184 msg: format!("zip_error: {:?}", e),
1185 origin: Some(BuckyOriginError::ZipError(e)),
1186 }
1187 }
1188}
1189
1190#[cfg(feature = "hex")]
1191impl From<hex::FromHexError> for BuckyError {
1192 fn from(e: hex::FromHexError) -> Self {
1193 BuckyError {
1194 code: BuckyErrorCode::HexError,
1195 msg: format!("hex error: {}", e),
1196 origin: Some(BuckyOriginError::HexError(e)),
1197 }
1198 }
1199}
1200
1201#[cfg(feature = "rsa")]
1202impl From<rsa::errors::Error> for BuckyError {
1203 fn from(e: rsa::errors::Error) -> Self {
1204 BuckyError {
1205 code: BuckyErrorCode::RsaError,
1206 msg: format!("rsa error: {:?}", e),
1207 origin: Some(BuckyOriginError::RsaError(e)),
1208 }
1209 }
1210}
1211
1212impl From<BuckyErrorCode> for BuckyError {
1213 fn from(code: BuckyErrorCode) -> BuckyError {
1214 BuckyError {
1215 code,
1216 msg: "".to_owned(),
1217 origin: None,
1218 }
1219 }
1220}
1221
1222impl From<&str> for BuckyError {
1223 fn from(msg: &str) -> BuckyError {
1224 BuckyError {
1225 code: BuckyErrorCode::Unknown,
1226 msg: msg.to_owned(),
1227 origin: None,
1228 }
1229 }
1230}
1231
1232impl From<String> for BuckyError {
1233 fn from(msg: String) -> BuckyError {
1234 BuckyError {
1235 code: BuckyErrorCode::Unknown,
1236 msg,
1237 origin: None,
1238 }
1239 }
1240}
1241
1242impl From<(BuckyErrorCode, &str)> for BuckyError {
1243 fn from(cm: (BuckyErrorCode, &str)) -> BuckyError {
1244 BuckyError {
1245 code: cm.0,
1246 msg: cm.1.to_owned(),
1247 origin: None,
1248 }
1249 }
1250}
1251
1252impl From<(BuckyErrorCode, String)> for BuckyError {
1253 fn from(cm: (BuckyErrorCode, String)) -> BuckyError {
1254 BuckyError {
1255 code: cm.0,
1256 msg: cm.1,
1257 origin: None,
1258 }
1259 }
1260}
1261
1262impl From<(BuckyErrorCode, String, Option<BuckyOriginError>)> for BuckyError {
1263 fn from(value: (BuckyErrorCode, String, Option<BuckyOriginError>)) -> Self {
1264 BuckyError {
1265 code: value.0,
1266 msg: value.1,
1267 origin: value.2,
1268 }
1269 }
1270}
1271
1272impl From<Box<dyn Error>> for BuckyError {
1295 fn from(err: Box<dyn Error>) -> BuckyError {
1296 if err.is::<BuckyError>() {
1297 let be = err.downcast::<BuckyError>().unwrap();
1298 *be
1299 } else {
1300 BuckyError {
1301 code: BuckyErrorCode::Unknown,
1302 msg: format!("{}", err),
1303 origin: None,
1304 }
1305 }
1306 }
1307}
1308
1309impl Into<BuckyErrorCode> for BuckyError {
1310 fn into(self) -> BuckyErrorCode {
1311 self.code
1312 }
1313}
1314
1315impl Into<ErrorKind> for BuckyErrorCode {
1316 fn into(self) -> ErrorKind {
1317 match self {
1318 Self::Reject | Self::PermissionDenied => ErrorKind::PermissionDenied,
1319 Self::NotFound => ErrorKind::NotFound,
1320
1321 Self::ConnectionReset => ErrorKind::ConnectionReset,
1322 Self::ConnectionRefused => ErrorKind::ConnectionRefused,
1323 Self::ConnectionAborted => ErrorKind::ConnectionAborted,
1324 Self::AddrInUse => ErrorKind::AddrInUse,
1325 Self::AddrNotAvailable => ErrorKind::AddrNotAvailable,
1326 Self::NotConnected => ErrorKind::NotConnected,
1327 Self::AlreadyExists => ErrorKind::AlreadyExists,
1328 Self::Interrupted => ErrorKind::Interrupted,
1329 Self::WriteZero => ErrorKind::WriteZero,
1330 Self::UnexpectedEof => ErrorKind::UnexpectedEof,
1331 Self::UnSupport => ErrorKind::Unsupported,
1332 Self::BrokenPipe => ErrorKind::BrokenPipe,
1333 Self::WouldBlock => ErrorKind::WouldBlock,
1334 Self::Timeout => ErrorKind::TimedOut,
1335 Self::OutOfLimit => ErrorKind::OutOfMemory,
1336
1337 _ => ErrorKind::Other,
1338 }
1339 }
1340}
1341#[cfg(test)]
1349mod tests {
1350 use crate::*;
1351 use serde::{Deserialize, Serialize};
1352
1353 #[derive(Debug, Eq, PartialEq, Serialize, Deserialize)]
1354 struct SimpleBuckyError {
1355 msg: String,
1356 code: BuckyErrorCode,
1357 }
1358
1359 fn re_error() -> BuckyError {
1360 BuckyError::from(BuckyErrorCode::Failed)
1361 }
1362
1363 fn re_error2() -> BuckyError {
1364 BuckyError::from(format!("test error"))
1365 }
1366
1367 #[test]
1368 fn test_codec() {
1369 let code = BuckyErrorCode::ErrorState;
1370 let v = serde_json::to_string(&code).unwrap();
1371 println!("error code: {}", v);
1372 let code2: BuckyErrorCode = serde_json::from_str(&v).unwrap();
1373 assert_eq!(code2, code);
1374
1375 let e = SimpleBuckyError {
1376 code: BuckyErrorCode::InvalidFormat,
1377 msg: "test".to_owned(),
1378 };
1379 let v = serde_json::to_string(&e).unwrap();
1380 println!("error: {}", v);
1381 let e2: SimpleBuckyError = serde_json::from_str(&v).unwrap();
1382 assert_eq!(e, e2);
1383 }
1384
1385 #[test]
1386 fn test_error() {
1387 let err = re_error();
1388 assert!(err.code() == BuckyErrorCode::Failed);
1389
1390 re_error2();
1391
1392 let user_error = 101;
1393 let code = BuckyErrorCode::DecError(user_error);
1394 let value: u16 = code.into();
1395 let code2 = BuckyErrorCode::from(value);
1396 assert_eq!(code, code2);
1397
1398 let user_error = u16::MAX;
1399 let code = BuckyErrorCode::DecError(user_error);
1400 let value: u16 = code.into();
1401 let code2 = BuckyErrorCode::from(value);
1402 assert_ne!(code, code2);
1403 let max_code = BuckyErrorCode::DecError(BUCKY_DEC_ERROR_CODE_MAX);
1404 assert_eq!(max_code, code2);
1405
1406 let code = BuckyErrorCode::Unknown;
1407 let value: u16 = code.into();
1408 let code2 = BuckyErrorCode::from(value);
1409 assert_eq!(code, code2);
1410 }
1411
1412
1413 #[test]
1414 fn test_io_error() {
1415 let err = BuckyError::new(BuckyErrorCode::AddrInUse, "invaid address");
1416 assert!(err.code() == BuckyErrorCode::AddrInUse);
1417
1418 let e = BuckyError::bucky_error_to_io_error(err.clone());
1419 let be = BuckyError::io_error_to_bucky_error(e);
1420 assert_eq!(be.code(), err.code());
1421 assert_eq!(be.msg(), err.msg());
1422
1423 let e: std::io::Error = err.clone().into();
1424 let be: BuckyError = e.into();
1425
1426 assert_eq!(be.code(), err.code());
1427 assert_eq!(be.msg(), err.msg());
1428 }
1429}