1use crate::codec as cyfs_base;
2use crate::*;
3
4use int_enum::IntEnum;
5use serde::de::{self, Visitor};
6use serde::{Deserialize, Deserializer, Serialize, Serializer};
7use std::error::Error;
8use std::fmt::{self, Debug, Display};
9use std::io::ErrorKind;
10pub const BUCKY_SYSTEM_ERROR_CODE_START: u16 = 0;
14pub const BUCKY_SYSTEM_ERROR_CODE_END: u16 = 5000;
15
16pub const BUCKY_META_ERROR_CODE_START: u16 = 5000;
19pub const BUCKY_META_ERROR_CODE_END: u16 = 6000;
20
21pub const BUCKY_META_ERROR_CODE_MAX: u16 =
22 BUCKY_META_ERROR_CODE_END - BUCKY_META_ERROR_CODE_START - 1;
23
24pub const BUCKY_DEC_ERROR_CODE_START: u16 = 15000;
27pub const BUCKY_DEC_ERROR_CODE_END: u16 = u16::MAX;
28
29pub const BUCKY_DEC_ERROR_CODE_MAX: u16 = BUCKY_DEC_ERROR_CODE_END - BUCKY_DEC_ERROR_CODE_START;
31
32pub fn is_system_error_code(code: u16) -> bool {
33 code < BUCKY_SYSTEM_ERROR_CODE_END
34}
35
36pub fn is_meta_error_code(code: u16) -> bool {
37 code >= BUCKY_META_ERROR_CODE_START && code < BUCKY_META_ERROR_CODE_END
38}
39
40pub fn is_dec_error_code(code: u16) -> bool {
41 code >= BUCKY_DEC_ERROR_CODE_START
42}
43
44#[repr(u16)]
46#[derive(
47 Debug, Clone, Copy, Eq, IntEnum, PartialEq, RawEncode, RawDecode, Serialize, Deserialize,
48)]
49pub enum BuckySystemErrorCode {
50 Ok = 0,
51
52 Failed = 1,
53 InvalidParam = 2,
54 Timeout = 3,
55 NotFound = 4,
56 AlreadyExists = 5,
57 NotSupport = 6,
58 ErrorState = 7,
59 InvalidFormat = 8,
60 Expired = 9,
61 OutOfLimit = 10,
62 InternalError = 11,
63
64 PermissionDenied = 12,
65 ConnectionRefused = 13,
66 ConnectionReset = 14,
67 ConnectionAborted = 15,
68 NotConnected = 16,
69 AddrInUse = 18,
70 AddrNotAvailable = 19,
71 Interrupted = 20,
72 InvalidInput = 21,
73 InvalidData = 22,
74 WriteZero = 23,
75 UnexpectedEof = 24,
76 BrokenPipe = 25,
77 WouldBlock = 26,
78
79 UnSupport = 27,
80 Unmatch = 28,
81 ExecuteError = 29,
82 Reject = 30,
83 Ignored = 31,
84 InvalidSignature = 32,
85 AlreadyExistsAndSignatureMerged = 33,
86 TargetNotFound = 34,
87 Aborted = 35,
88
89 ConnectFailed = 40,
90 ConnectInterZoneFailed = 41,
91 InnerPathNotFound = 42,
92 RangeNotSatisfiable = 43,
93 UserCanceled = 44,
94 Conflict = 50,
95
96 OutofSessionLimit = 60,
97
98 Redirect = 66,
99
100 MongoDBError = 99,
101 SqliteError = 100,
102 UrlError = 101,
103 ZipError = 102,
104 HttpError = 103,
105 JsonError = 104,
106 HexError = 105,
107 RsaError = 106,
108 CryptoError = 107,
109 MpscSendError = 108,
110 MpscRecvError = 109,
111 IoError = 110,
112 NetworkError = 111,
113
114 CodeError = 250, UnknownBdtError = 253,
116 UnknownIOError = 254,
117 Unknown = 255,
118
119 Pending = 256,
120 NotChange = 257,
121
122 NotMatch = 258,
123 NotImplement = 259,
124 NotInit = 260,
125 ParseError = 261,
126 NotHandled = 262,
127
128 MetaError = 5000,
130
131 DecError = 15000,
133}
134
135impl Into<u16> for BuckySystemErrorCode {
136 fn into(self) -> u16 {
137 unsafe { std::mem::transmute(self as u16) }
138 }
139}
140
141impl From<u16> for BuckySystemErrorCode {
142 fn from(code: u16) -> Self {
143 match Self::from_int(code) {
144 Ok(code) => code,
145 Err(e) => {
146 error!("unknown system error code: {} {}", code, e);
147 if is_dec_error_code(code) {
148 Self::DecError
149 } else if is_meta_error_code(code) {
150 Self::MetaError
151 } else {
152 Self::Unknown
153 }
154 }
155 }
156 }
157}
158
159#[repr(u16)]
161#[derive(Debug, Clone, Copy, Eq, PartialEq, RawEncode, RawDecode)]
162pub enum BuckyErrorCode {
163 Ok,
164
165 Failed,
166 InvalidParam,
167 Timeout,
168 NotFound,
169 AlreadyExists,
170 NotSupport,
171 ErrorState,
172 InvalidFormat,
173 Expired,
174 OutOfLimit,
175 InternalError,
176
177 PermissionDenied,
178 ConnectionRefused,
179 ConnectionReset,
180 ConnectionAborted,
181 NotConnected,
182 AddrInUse,
183 AddrNotAvailable,
184 Interrupted,
185 InvalidInput,
186 InvalidData,
187 WriteZero,
188 UnexpectedEof,
189 BrokenPipe,
190 WouldBlock,
191
192 UnSupport,
193 Unmatch,
194 ExecuteError,
195 Reject,
196 Ignored,
197 InvalidSignature,
198 AlreadyExistsAndSignatureMerged,
199 TargetNotFound,
200 Aborted,
201
202 ConnectFailed,
203 ConnectInterZoneFailed,
204 InnerPathNotFound,
205 RangeNotSatisfiable,
206 UserCanceled,
207
208 Conflict,
209
210 OutofSessionLimit,
211
212 Redirect,
213
214 MongoDBError,
215 SqliteError,
216 UrlError,
217 ZipError,
218 HttpError,
219 JsonError,
220 HexError,
221 RsaError,
222 CryptoError,
223 MpscSendError,
224 MpscRecvError,
225 IoError,
226 NetworkError,
227
228 CodeError, UnknownBdtError,
230 UnknownIOError,
231 Unknown,
232
233 Pending,
234 NotChange,
235
236 NotMatch,
237 NotImplement,
238 NotInit,
239
240 ParseError,
241 NotHandled,
242
243 MetaError(u16),
245
246 DecError(u16),
248}
249
250impl Into<BuckySystemErrorCode> for BuckyErrorCode {
251 fn into(self) -> BuckySystemErrorCode {
252 match self {
253 Self::Ok => BuckySystemErrorCode::Ok,
254
255 Self::Failed => BuckySystemErrorCode::Failed,
256 Self::InvalidParam => BuckySystemErrorCode::InvalidParam,
257 Self::Timeout => BuckySystemErrorCode::Timeout,
258 Self::NotFound => BuckySystemErrorCode::NotFound,
259 Self::AlreadyExists => BuckySystemErrorCode::AlreadyExists,
260 Self::NotSupport => BuckySystemErrorCode::NotSupport,
261 Self::ErrorState => BuckySystemErrorCode::ErrorState,
262 Self::InvalidFormat => BuckySystemErrorCode::InvalidFormat,
263 Self::Expired => BuckySystemErrorCode::Expired,
264 Self::OutOfLimit => BuckySystemErrorCode::OutOfLimit,
265 Self::InternalError => BuckySystemErrorCode::InternalError,
266
267 Self::PermissionDenied => BuckySystemErrorCode::PermissionDenied,
268 Self::ConnectionRefused => BuckySystemErrorCode::ConnectionRefused,
269 Self::ConnectionReset => BuckySystemErrorCode::ConnectionReset,
270 Self::ConnectionAborted => BuckySystemErrorCode::ConnectionAborted,
271 Self::NotConnected => BuckySystemErrorCode::NotConnected,
272 Self::AddrInUse => BuckySystemErrorCode::AddrInUse,
273 Self::AddrNotAvailable => BuckySystemErrorCode::AddrNotAvailable,
274 Self::Interrupted => BuckySystemErrorCode::Interrupted,
275 Self::InvalidInput => BuckySystemErrorCode::InvalidInput,
276 Self::InvalidData => BuckySystemErrorCode::InvalidData,
277 Self::WriteZero => BuckySystemErrorCode::WriteZero,
278 Self::UnexpectedEof => BuckySystemErrorCode::UnexpectedEof,
279 Self::BrokenPipe => BuckySystemErrorCode::BrokenPipe,
280 Self::WouldBlock => BuckySystemErrorCode::WouldBlock,
281
282 Self::UnSupport => BuckySystemErrorCode::UnSupport,
283 Self::Unmatch => BuckySystemErrorCode::Unmatch,
284 Self::ExecuteError => BuckySystemErrorCode::ExecuteError,
285 Self::Reject => BuckySystemErrorCode::Reject,
286 Self::Ignored => BuckySystemErrorCode::Ignored,
287 Self::InvalidSignature => BuckySystemErrorCode::InvalidSignature,
288 Self::AlreadyExistsAndSignatureMerged => {
289 BuckySystemErrorCode::AlreadyExistsAndSignatureMerged
290 }
291 Self::TargetNotFound => BuckySystemErrorCode::TargetNotFound,
292 Self::Aborted => BuckySystemErrorCode::Aborted,
293
294 Self::ConnectFailed => BuckySystemErrorCode::ConnectFailed,
295 Self::ConnectInterZoneFailed => BuckySystemErrorCode::ConnectInterZoneFailed,
296 Self::InnerPathNotFound => BuckySystemErrorCode::InnerPathNotFound,
297 Self::RangeNotSatisfiable => BuckySystemErrorCode::RangeNotSatisfiable,
298 Self::UserCanceled => BuckySystemErrorCode::UserCanceled,
299 Self::Conflict => BuckySystemErrorCode::Conflict,
300
301 Self::OutofSessionLimit => BuckySystemErrorCode::OutofSessionLimit,
302 Self::Redirect => BuckySystemErrorCode::Redirect,
303
304 Self::MongoDBError => BuckySystemErrorCode::MongoDBError,
305 Self::SqliteError => BuckySystemErrorCode::SqliteError,
306 Self::UrlError => BuckySystemErrorCode::UrlError,
307 Self::ZipError => BuckySystemErrorCode::ZipError,
308 Self::HttpError => BuckySystemErrorCode::HttpError,
309 Self::JsonError => BuckySystemErrorCode::JsonError,
310 Self::HexError => BuckySystemErrorCode::RsaError,
311 Self::RsaError => BuckySystemErrorCode::InternalError,
312 Self::CryptoError => BuckySystemErrorCode::CryptoError,
313 Self::MpscSendError => BuckySystemErrorCode::MpscSendError,
314 Self::MpscRecvError => BuckySystemErrorCode::MpscRecvError,
315 Self::IoError => BuckySystemErrorCode::IoError,
316 Self::NetworkError => BuckySystemErrorCode::NetworkError,
317
318 Self::CodeError => BuckySystemErrorCode::CodeError,
319 Self::UnknownBdtError => BuckySystemErrorCode::UnknownBdtError,
320 Self::UnknownIOError => BuckySystemErrorCode::UnknownIOError,
321 Self::Unknown => BuckySystemErrorCode::Unknown,
322
323 Self::Pending => BuckySystemErrorCode::Pending,
324 Self::NotChange => BuckySystemErrorCode::NotChange,
325
326 Self::NotMatch => BuckySystemErrorCode::NotMatch,
327 Self::NotImplement => BuckySystemErrorCode::NotImplement,
328 Self::NotInit => BuckySystemErrorCode::NotInit,
329
330 Self::ParseError => BuckySystemErrorCode::ParseError,
331 Self::NotHandled => BuckySystemErrorCode::NotHandled,
332
333 Self::MetaError(_) => BuckySystemErrorCode::MetaError,
334 Self::DecError(_) => BuckySystemErrorCode::DecError,
335 }
336 }
337}
338
339impl Into<BuckyErrorCode> for BuckySystemErrorCode {
340 fn into(self) -> BuckyErrorCode {
341 match self {
342 Self::Ok => BuckyErrorCode::Ok,
343
344 Self::Failed => BuckyErrorCode::Failed,
345 Self::InvalidParam => BuckyErrorCode::InvalidParam,
346 Self::Timeout => BuckyErrorCode::Timeout,
347 Self::NotFound => BuckyErrorCode::NotFound,
348 Self::AlreadyExists => BuckyErrorCode::AlreadyExists,
349 Self::NotSupport => BuckyErrorCode::NotSupport,
350 Self::ErrorState => BuckyErrorCode::ErrorState,
351 Self::InvalidFormat => BuckyErrorCode::InvalidFormat,
352 Self::Expired => BuckyErrorCode::Expired,
353 Self::OutOfLimit => BuckyErrorCode::OutOfLimit,
354 Self::InternalError => BuckyErrorCode::InternalError,
355
356 Self::PermissionDenied => BuckyErrorCode::PermissionDenied,
357 Self::ConnectionRefused => BuckyErrorCode::ConnectionRefused,
358 Self::ConnectionReset => BuckyErrorCode::ConnectionReset,
359 Self::ConnectionAborted => BuckyErrorCode::ConnectionAborted,
360 Self::NotConnected => BuckyErrorCode::NotConnected,
361 Self::AddrInUse => BuckyErrorCode::AddrInUse,
362 Self::AddrNotAvailable => BuckyErrorCode::AddrNotAvailable,
363 Self::Interrupted => BuckyErrorCode::Interrupted,
364 Self::InvalidInput => BuckyErrorCode::InvalidInput,
365 Self::InvalidData => BuckyErrorCode::InvalidData,
366 Self::WriteZero => BuckyErrorCode::WriteZero,
367 Self::UnexpectedEof => BuckyErrorCode::UnexpectedEof,
368 Self::BrokenPipe => BuckyErrorCode::BrokenPipe,
369 Self::WouldBlock => BuckyErrorCode::WouldBlock,
370
371 Self::UnSupport => BuckyErrorCode::UnSupport,
372 Self::Unmatch => BuckyErrorCode::Unmatch,
373 Self::ExecuteError => BuckyErrorCode::ExecuteError,
374 Self::Reject => BuckyErrorCode::Reject,
375 Self::Ignored => BuckyErrorCode::Ignored,
376 Self::InvalidSignature => BuckyErrorCode::InvalidSignature,
377 Self::AlreadyExistsAndSignatureMerged => {
378 BuckyErrorCode::AlreadyExistsAndSignatureMerged
379 }
380 Self::TargetNotFound => BuckyErrorCode::TargetNotFound,
381 Self::Aborted => BuckyErrorCode::Aborted,
382
383 Self::ConnectFailed => BuckyErrorCode::ConnectFailed,
384 Self::ConnectInterZoneFailed => BuckyErrorCode::ConnectInterZoneFailed,
385 Self::InnerPathNotFound => BuckyErrorCode::InnerPathNotFound,
386 Self::RangeNotSatisfiable => BuckyErrorCode::RangeNotSatisfiable,
387 Self::UserCanceled => BuckyErrorCode::UserCanceled,
388
389 Self::Conflict => BuckyErrorCode::Conflict,
390
391 Self::OutofSessionLimit => BuckyErrorCode::OutofSessionLimit,
392
393 Self::Redirect => BuckyErrorCode::Redirect,
394
395 Self::MongoDBError => BuckyErrorCode::MongoDBError,
396 Self::SqliteError => BuckyErrorCode::SqliteError,
397 Self::UrlError => BuckyErrorCode::UrlError,
398 Self::ZipError => BuckyErrorCode::ZipError,
399 Self::HttpError => BuckyErrorCode::HttpError,
400 Self::JsonError => BuckyErrorCode::JsonError,
401 Self::HexError => BuckyErrorCode::RsaError,
402 Self::RsaError => BuckyErrorCode::InternalError,
403 Self::CryptoError => BuckyErrorCode::CryptoError,
404 Self::MpscSendError => BuckyErrorCode::MpscSendError,
405 Self::MpscRecvError => BuckyErrorCode::MpscRecvError,
406 Self::IoError => BuckyErrorCode::IoError,
407 Self::NetworkError => BuckyErrorCode::NetworkError,
408
409 Self::CodeError => BuckyErrorCode::CodeError,
410 Self::UnknownBdtError => BuckyErrorCode::UnknownBdtError,
411 Self::UnknownIOError => BuckyErrorCode::UnknownIOError,
412 Self::Unknown => BuckyErrorCode::Unknown,
413
414 Self::Pending => BuckyErrorCode::Pending,
415 Self::NotChange => BuckyErrorCode::NotChange,
416
417 Self::NotMatch => BuckyErrorCode::NotMatch,
418 Self::NotImplement => BuckyErrorCode::NotImplement,
419 Self::NotInit => BuckyErrorCode::NotInit,
420
421 Self::ParseError => BuckyErrorCode::ParseError,
422 Self::NotHandled => BuckyErrorCode::NotHandled,
423
424 Self::MetaError => BuckyErrorCode::MetaError(0),
425 Self::DecError => BuckyErrorCode::DecError(0),
426 }
427 }
428}
429
430impl Into<u32> for BuckyErrorCode {
431 fn into(self) -> u32 {
432 let v: u16 = self.into();
433 v as u32
434 }
435}
436
437impl Into<i32> for BuckyErrorCode {
438 fn into(self) -> i32 {
439 let v: u16 = self.into();
440 v as i32
441 }
442}
443
444impl Into<u16> for BuckyErrorCode {
445 fn into(self) -> u16 {
446 match self {
447 Self::MetaError(mut v) => {
448 if v > BUCKY_META_ERROR_CODE_MAX {
449 error!("meta error code out of limit: {}", v);
450 v = BUCKY_META_ERROR_CODE_MAX;
451 }
452
453 BUCKY_META_ERROR_CODE_START + v
454 }
455 Self::DecError(mut v) => {
456 if v > BUCKY_DEC_ERROR_CODE_MAX {
457 error!("dec error code out of limit: {}", v);
458 v = BUCKY_DEC_ERROR_CODE_MAX;
459 }
460
461 BUCKY_DEC_ERROR_CODE_START + v
462 }
463 _ => Into::<BuckySystemErrorCode>::into(self).into(),
464 }
465 }
466}
467
468impl From<u16> for BuckyErrorCode {
469 fn from(code: u16) -> Self {
470 if is_system_error_code(code) {
471 BuckySystemErrorCode::from(code).into()
472 } else if is_meta_error_code(code) {
473 let code = code - BUCKY_META_ERROR_CODE_START;
474 Self::MetaError(code)
475 } else if is_dec_error_code(code) {
476 let code = code - BUCKY_DEC_ERROR_CODE_START;
477 Self::DecError(code)
478 } else {
479 error!("unknown error code: {}", code);
480 Self::Unknown
481 }
482 }
483}
484
485impl From<u32> for BuckyErrorCode {
486 fn from(code: u32) -> Self {
487 if code < u16::MAX as u32 {
488 Self::from(code as u16)
489 } else {
490 error!("u32 error code out of u16 limit: {}", code);
491 Self::Unknown
492 }
493 }
494}
495
496impl Display for BuckyErrorCode {
497 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
498 write!(f, "{}", self.as_u16())
499 }
500}
501
502impl Serialize for BuckyErrorCode {
503 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
504 where
505 S: Serializer,
506 {
507 serializer.serialize_u16(self.as_u16())
508 }
509}
510
511struct BuckyErrorCodeVisitor {}
512impl<'de> Visitor<'de> for BuckyErrorCodeVisitor {
513 type Value = BuckyErrorCode;
514
515 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
516 formatter.write_str("u16")
517 }
518
519 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
520 where
521 E: de::Error,
522 {
523 if v < u16::MAX as u64 {
524 Ok(BuckyErrorCode::from(v as u16))
525 } else {
526 error!("invalid BuckyErrorCode int value: {}", v);
527 Ok(BuckyErrorCode::Unknown)
528 }
529 }
530}
531
532impl<'de> Deserialize<'de> for BuckyErrorCode {
533 fn deserialize<D>(deserializer: D) -> Result<BuckyErrorCode, D::Error>
534 where
535 D: Deserializer<'de>,
536 {
537 deserializer.deserialize_u16(BuckyErrorCodeVisitor {})
538 }
539}
540
541impl BuckyErrorCode {
542 pub fn as_u8(&self) -> u8 {
543 let v: u16 = self.clone().into();
544 v as u8
545 }
546
547 pub fn into_u8(self) -> u8 {
548 let v: u16 = self.into();
549 v as u8
550 }
551
552 pub fn as_u16(&self) -> u16 {
553 self.clone().into()
554 }
555
556 pub fn into_u16(self) -> u16 {
557 self.into()
558 }
559
560 pub fn is_meta_error(&self) -> bool {
562 match *self {
563 Self::MetaError(_) => true,
564 _ => false,
565 }
566 }
567
568 pub fn is_dec_error(&self) -> bool {
570 match *self {
571 Self::DecError(_) => true,
572 _ => false,
573 }
574 }
575}
576
577pub enum BuckyErrorCodeEx {
579 System(BuckySystemErrorCode),
580 MetaError(u16),
581 DecError(u16),
582}
583
584impl Into<BuckyErrorCode> for BuckyErrorCodeEx {
585 fn into(self) -> BuckyErrorCode {
586 match self {
587 Self::System(code) => code.into(),
588 Self::MetaError(v) => BuckyErrorCode::MetaError(v),
589 Self::DecError(v) => BuckyErrorCode::DecError(v),
590 }
591 }
592}
593
594impl Into<BuckyErrorCodeEx> for BuckyErrorCode {
595 fn into(self) -> BuckyErrorCodeEx {
596 match self {
597 Self::MetaError(v) => BuckyErrorCodeEx::MetaError(v),
598 Self::DecError(v) => BuckyErrorCodeEx::DecError(v),
599 _ => self.into(),
600 }
601 }
602}
603
604impl Into<BuckyErrorCodeEx> for BuckySystemErrorCode {
605 fn into(self) -> BuckyErrorCodeEx {
606 BuckyErrorCodeEx::System(self)
607 }
608}
609
610#[derive(Debug)]
612pub enum BuckyOriginError {
613 IoError(std::io::Error),
614 SerdeJsonError(serde_json::error::Error),
615 HttpError(http_types::Error),
616 UrlError(url::ParseError),
617 #[cfg(not(target_arch = "wasm32"))]
618 ZipError(zip::result::ZipError),
619 HttpStatusCodeError(http_types::StatusCode),
620 #[cfg(not(target_arch = "wasm32"))]
621 SqliteError(rusqlite::Error),
622 #[cfg(feature = "sqlx-error")]
623 SqlxError(sqlx::Error),
624 HexError(hex::FromHexError),
625 RsaError(rsa::errors::Error),
626 CodeError(u32),
627 ParseIntError(std::num::ParseIntError),
628 ParseFloatError(std::num::ParseFloatError),
629 AddrParseError(std::net::AddrParseError),
630 StripPrefixError(std::path::StripPrefixError),
631 ParseUtf8Error(std::str::Utf8Error),
632 ErrorMsg(String),
633}
634
635impl RawEncode for BuckyOriginError {
636 fn raw_measure(&self, purpose: &Option<RawEncodePurpose>) -> BuckyResult<usize> {
637 if cfg!(not(target_arch = "wasm32")) {
638 if let BuckyOriginError::ZipError(e) = self {
639 let msg = format!("{:?}", e);
640 return Ok(USize(2).raw_measure(purpose)? + msg.raw_measure(purpose)?);
641 }
642
643 if let BuckyOriginError::SqliteError(e) = self {
644 let msg = format!("{:?}", e);
645 return Ok(USize(2).raw_measure(purpose)? + msg.raw_measure(purpose)?);
646 }
647 }
648
649 match self {
650 BuckyOriginError::IoError(e) => {
651 let msg = format!("{:?}", e);
652 Ok(USize(2).raw_measure(purpose)? + msg.raw_measure(purpose)?)
653 }
654 BuckyOriginError::SerdeJsonError(e) => {
655 let msg = format!("{:?}", e);
656 Ok(USize(2).raw_measure(purpose)? + msg.raw_measure(purpose)?)
657 }
658 BuckyOriginError::HttpError(e) => {
659 let msg = format!("{:?}", e);
660 Ok(USize(2).raw_measure(purpose)? + msg.raw_measure(purpose)?)
661 }
662 BuckyOriginError::UrlError(e) => {
663 let msg = format!("{:?}", e);
664 Ok(USize(2).raw_measure(purpose)? + msg.raw_measure(purpose)?)
665 }
666 BuckyOriginError::HttpStatusCodeError(e) => {
667 let msg = format!("{:?}", e);
668 Ok(USize(2).raw_measure(purpose)? + msg.raw_measure(purpose)?)
669 }
670 BuckyOriginError::HexError(e) => {
671 let msg = format!("{:?}", e);
672 Ok(USize(2).raw_measure(purpose)? + msg.raw_measure(purpose)?)
673 }
674 BuckyOriginError::RsaError(e) => {
675 let msg = format!("{:?}", e);
676 Ok(USize(2).raw_measure(purpose)? + msg.raw_measure(purpose)?)
677 }
678 BuckyOriginError::CodeError(e) => {
679 Ok(USize(1).raw_measure(purpose)? + e.raw_measure(purpose)?)
680 }
681 BuckyOriginError::ParseIntError(e) => {
682 let msg = format!("{:?}", e);
683 Ok(USize(2).raw_measure(purpose)? + msg.raw_measure(purpose)?)
684 }
685 BuckyOriginError::ParseFloatError(e) => {
686 let msg = format!("{:?}", e);
687 Ok(USize(2).raw_measure(purpose)? + msg.raw_measure(purpose)?)
688 }
689 BuckyOriginError::AddrParseError(e) => {
690 let msg = format!("{:?}", e);
691 Ok(USize(2).raw_measure(purpose)? + msg.raw_measure(purpose)?)
692 }
693 BuckyOriginError::StripPrefixError(e) => {
694 let msg = format!("{:?}", e);
695 Ok(USize(2).raw_measure(purpose)? + msg.raw_measure(purpose)?)
696 }
697 BuckyOriginError::ParseUtf8Error(e) => {
698 let msg = format!("{:?}", e);
699 Ok(USize(2).raw_measure(purpose)? + msg.raw_measure(purpose)?)
700 }
701 BuckyOriginError::ErrorMsg(msg) => {
702 Ok(USize(2).raw_measure(purpose)? + msg.raw_measure(purpose)?)
703 }
704 #[cfg(feature = "sqlx-error")]
705 BuckyOriginError::SqlxError(e) => {
706 let msg = format!("{:?}", e);
707 Ok(USize(2).raw_measure(purpose)? + msg.raw_measure(purpose)?)
708 }
709 _ => Ok(USize(3).raw_measure(purpose)?),
710 }
711 }
712
713 fn raw_encode<'a>(
714 &self,
715 buf: &'a mut [u8],
716 purpose: &Option<RawEncodePurpose>,
717 ) -> BuckyResult<&'a mut [u8]> {
718 if cfg!(not(target_arch = "wasm32")) {
719 if let BuckyOriginError::ZipError(e) = self {
720 let msg = format!("{:?}", e);
721 let buf = USize(2).raw_encode(buf, purpose)?;
722 let buf = msg.raw_encode(buf, purpose)?;
723 return Ok(buf);
724 }
725
726 if let BuckyOriginError::SqliteError(e) = self {
727 let msg = format!("{:?}", e);
728 let buf = USize(2).raw_encode(buf, purpose)?;
729 let buf = msg.raw_encode(buf, purpose)?;
730 return Ok(buf);
731 }
732 }
733
734 match self {
735 BuckyOriginError::IoError(e) => {
736 let msg = format!("{:?}", e);
737 let buf = USize(2).raw_encode(buf, purpose)?;
738 let buf = msg.raw_encode(buf, purpose)?;
739 Ok(buf)
740 }
741 BuckyOriginError::SerdeJsonError(e) => {
742 let msg = format!("{:?}", e);
743 let buf = USize(2).raw_encode(buf, purpose)?;
744 let buf = msg.raw_encode(buf, purpose)?;
745 Ok(buf)
746 }
747 BuckyOriginError::HttpError(e) => {
748 let msg = format!("{:?}", e);
749 let buf = USize(2).raw_encode(buf, purpose)?;
750 let buf = msg.raw_encode(buf, purpose)?;
751 Ok(buf)
752 }
753 BuckyOriginError::UrlError(e) => {
754 let msg = format!("{:?}", e);
755 let buf = USize(2).raw_encode(buf, purpose)?;
756 let buf = msg.raw_encode(buf, purpose)?;
757 Ok(buf)
758 }
759 BuckyOriginError::HttpStatusCodeError(e) => {
760 let msg = format!("{:?}", e);
761 let buf = USize(2).raw_encode(buf, purpose)?;
762 let buf = msg.raw_encode(buf, purpose)?;
763 Ok(buf)
764 }
765 BuckyOriginError::HexError(e) => {
766 let msg = format!("{:?}", e);
767 let buf = USize(2).raw_encode(buf, purpose)?;
768 let buf = msg.raw_encode(buf, purpose)?;
769 Ok(buf)
770 }
771 BuckyOriginError::RsaError(e) => {
772 let msg = format!("{:?}", e);
773 let buf = USize(2).raw_encode(buf, purpose)?;
774 let buf = msg.raw_encode(buf, purpose)?;
775 Ok(buf)
776 }
777 BuckyOriginError::CodeError(e) => {
778 let buf = USize(1).raw_encode(buf, purpose)?;
779 let buf = e.raw_encode(buf, purpose)?;
780 Ok(buf)
781 }
782 BuckyOriginError::ParseIntError(e) => {
783 let msg = format!("{:?}", e);
784 let buf = USize(2).raw_encode(buf, purpose)?;
785 let buf = msg.raw_encode(buf, purpose)?;
786 Ok(buf)
787 }
788 BuckyOriginError::ParseFloatError(e) => {
789 let msg = format!("{:?}", e);
790 let buf = USize(2).raw_encode(buf, purpose)?;
791 let buf = msg.raw_encode(buf, purpose)?;
792 Ok(buf)
793 }
794 BuckyOriginError::AddrParseError(e) => {
795 let msg = format!("{:?}", e);
796 let buf = USize(2).raw_encode(buf, purpose)?;
797 let buf = msg.raw_encode(buf, purpose)?;
798 Ok(buf)
799 }
800 BuckyOriginError::StripPrefixError(e) => {
801 let msg = format!("{:?}", e);
802 let buf = USize(2).raw_encode(buf, purpose)?;
803 let buf = msg.raw_encode(buf, purpose)?;
804 Ok(buf)
805 }
806 BuckyOriginError::ParseUtf8Error(e) => {
807 let msg = format!("{:?}", e);
808 let buf = USize(2).raw_encode(buf, purpose)?;
809 let buf = msg.raw_encode(buf, purpose)?;
810 Ok(buf)
811 }
812 BuckyOriginError::ErrorMsg(msg) => {
813 let buf = USize(2).raw_encode(buf, purpose)?;
814 let buf = msg.raw_encode(buf, purpose)?;
815 Ok(buf)
816 }
817 #[cfg(feature = "sqlx-error")]
818 BuckyOriginError::SqlxError(e) => {
819 let msg = format!("{:?}", e);
820 let buf = USize(2).raw_encode(buf, purpose)?;
821 let buf = msg.raw_encode(buf, purpose)?;
822 Ok(buf)
823 }
824 _ => {
825 let buf = USize(3).raw_encode(buf, purpose)?;
826 Ok(buf)
827 }
828 }
829 }
830}
831
832impl<'de> RawDecode<'de> for BuckyOriginError {
833 fn raw_decode(buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
834 let (t, buf) = USize::raw_decode(buf)?;
835 return if t.0 == 1 {
836 let (code, buf) = u32::raw_decode(buf)?;
837 Ok((BuckyOriginError::CodeError(code), buf))
838 } else if t.0 == 2 {
839 let (msg, buf) = String::raw_decode(buf)?;
840 Ok((BuckyOriginError::ErrorMsg(msg), buf))
841 } else {
842 Ok((BuckyOriginError::ErrorMsg("".to_string()), buf))
843 };
844 }
845}
846
847#[derive(RawEncode, RawDecode)]
848pub struct BuckyError {
849 code: BuckyErrorCode,
850 msg: String,
851
852 origin: Option<BuckyOriginError>,
853}
854
855pub type BuckyResult<T> = Result<T, BuckyError>;
856
857impl Clone for BuckyError {
860 fn clone(&self) -> Self {
861 BuckyError::new(self.code(), self.msg())
862 }
863}
864
865impl BuckyError {
866 pub fn new(code: impl Into<BuckyErrorCode>, msg: impl Into<String>) -> Self {
867 Self {
868 code: code.into(),
869 msg: msg.into(),
870 origin: None,
871 }
872 }
873
874 pub fn set_code(&mut self, code: impl Into<BuckyErrorCode>) {
875 self.code = code.into();
876 }
877
878 pub fn code(&self) -> BuckyErrorCode {
879 self.code
880 }
881
882 pub fn with_code(mut self, code: impl Into<BuckyErrorCode>) -> Self {
883 self.code = code.into();
884 self
885 }
886
887 pub fn set_msg(&mut self, msg: impl Into<String>) {
888 self.msg = msg.into();
889 }
890
891 pub fn msg(&self) -> &str {
892 self.msg.as_ref()
893 }
894
895 pub fn with_msg(mut self, msg: impl Into<String>) -> Self {
896 self.msg = msg.into();
897 self
898 }
899
900 pub fn origin(&self) -> &Option<BuckyOriginError> {
901 &self.origin
902 }
903
904 pub fn into_origin(self) -> Option<BuckyOriginError> {
905 self.origin
906 }
907
908 fn format(&self) -> String {
909 format!("err: ({:?}, {}, {:?})", self.code, self.msg, self.origin)
910 }
911
912 pub fn error_with_log<T>(msg: impl Into<String> + std::fmt::Display) -> BuckyResult<T> {
913 error!("{}", msg);
914
915 Err(BuckyError::new(BuckyErrorCode::Failed, msg))
916 }
917}
918
919impl Error for BuckyError {}
920
921impl Display for BuckyError {
922 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
923 Display::fmt(&self.format(), f)
924 }
925}
926
927impl Debug for BuckyError {
928 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
929 Debug::fmt(&self.format(), f)
930 }
931}
932
933impl BuckyError {
934 fn io_error_kind_to_code(kind: std::io::ErrorKind) -> BuckyErrorCode {
935 match kind {
936 ErrorKind::NotFound => BuckyErrorCode::NotFound,
937 ErrorKind::PermissionDenied => BuckyErrorCode::PermissionDenied,
938 ErrorKind::ConnectionRefused => BuckyErrorCode::ConnectionRefused,
939 ErrorKind::ConnectionReset => BuckyErrorCode::ConnectionReset,
940 ErrorKind::ConnectionAborted => BuckyErrorCode::ConnectionAborted,
941 ErrorKind::NotConnected => BuckyErrorCode::NotConnected,
942 ErrorKind::AddrInUse => BuckyErrorCode::AddrInUse,
943 ErrorKind::AddrNotAvailable => BuckyErrorCode::AddrNotAvailable,
944 ErrorKind::BrokenPipe => BuckyErrorCode::BrokenPipe,
945 ErrorKind::AlreadyExists => BuckyErrorCode::AlreadyExists,
946 ErrorKind::WouldBlock => BuckyErrorCode::WouldBlock,
947 ErrorKind::InvalidInput => BuckyErrorCode::InvalidInput,
948 ErrorKind::InvalidData => BuckyErrorCode::InvalidData,
949 ErrorKind::TimedOut => BuckyErrorCode::Timeout,
950 ErrorKind::WriteZero => BuckyErrorCode::WriteZero,
951 ErrorKind::Interrupted => BuckyErrorCode::Interrupted,
952 ErrorKind::UnexpectedEof => BuckyErrorCode::UnexpectedEof,
953 _ => BuckyErrorCode::UnknownIOError,
954 }
955 }
956
957 fn convert_bdt_error_code(code: u32) -> BuckyErrorCode {
964 match code {
965 _ => BuckyErrorCode::UnknownBdtError,
966 }
967 }
968
969 fn bucky_error_to_io_error(e: BuckyError) -> std::io::Error {
970 std::io::Error::new(std::io::ErrorKind::Other, e)
971 }
972
973 fn io_error_to_bucky_error(e: std::io::Error) -> BuckyError {
974 let kind = e.kind();
975 if kind == std::io::ErrorKind::Other && e.get_ref().is_some() {
976 match e.into_inner().unwrap().downcast::<BuckyError>() {
977 Ok(e) => {
978 e.as_ref().clone()
979 }
980 Err(e) => {
981 BuckyError {
982 code: Self::io_error_kind_to_code(kind),
983 msg: format!("io_error: {}", e),
984 origin: None,
985 }
986 }
987 }
988 } else {
989 BuckyError {
990 code: Self::io_error_kind_to_code(e.kind()),
991 msg: format!("io_error: {}", e),
992 origin: Some(BuckyOriginError::IoError(e)),
993 }
994 }
995 }
996}
997
998impl From<std::io::Error> for BuckyError {
999 fn from(err: std::io::Error) -> BuckyError {
1000 BuckyError::io_error_to_bucky_error(err)
1001 }
1002}
1003
1004impl From<BuckyError> for std::io::Error {
1005 fn from(err: BuckyError) -> std::io::Error {
1006 BuckyError::bucky_error_to_io_error(err)
1007 }
1008}
1009
1010impl From<std::str::Utf8Error> for BuckyError {
1011 fn from(err: std::str::Utf8Error) -> BuckyError {
1012 BuckyError {
1013 code: BuckyErrorCode::InvalidFormat,
1014 msg: format!("io_error: {}", err),
1015 origin: Some(BuckyOriginError::ParseUtf8Error(err)),
1016 }
1017 }
1018}
1019
1020impl From<http_types::Error> for BuckyError {
1021 fn from(err: http_types::Error) -> BuckyError {
1022 BuckyError {
1023 code: BuckyErrorCode::HttpError,
1024 msg: format!("http_error: {}", err),
1025 origin: Some(BuckyOriginError::HttpError(err)),
1026 }
1027 }
1028}
1029
1030impl From<std::num::ParseIntError> for BuckyError {
1031 fn from(err: std::num::ParseIntError) -> BuckyError {
1032 BuckyError {
1033 code: BuckyErrorCode::InvalidFormat,
1034 msg: format!("parse_int_error: {}", err),
1035 origin: Some(BuckyOriginError::ParseIntError(err)),
1036 }
1037 }
1038}
1039
1040impl From<std::num::ParseFloatError> for BuckyError {
1041 fn from(err: std::num::ParseFloatError) -> BuckyError {
1042 BuckyError {
1043 code: BuckyErrorCode::InvalidFormat,
1044 msg: format!("parse_int_error: {}", err),
1045 origin: Some(BuckyOriginError::ParseFloatError(err)),
1046 }
1047 }
1048}
1049
1050impl From<std::net::AddrParseError> for BuckyError {
1051 fn from(err: std::net::AddrParseError) -> BuckyError {
1052 BuckyError {
1053 code: BuckyErrorCode::InvalidFormat,
1054 msg: format!("parse_int_error: {}", err),
1055 origin: Some(BuckyOriginError::AddrParseError(err)),
1056 }
1057 }
1058}
1059
1060impl From<std::path::StripPrefixError> for BuckyError {
1061 fn from(err: std::path::StripPrefixError) -> BuckyError {
1062 BuckyError {
1063 code: BuckyErrorCode::InvalidFormat,
1064 msg: format!("strip_prefix_error: {}", err),
1065 origin: Some(BuckyOriginError::StripPrefixError(err)),
1066 }
1067 }
1068}
1069
1070impl From<async_std::future::TimeoutError> for BuckyError {
1071 fn from(err: async_std::future::TimeoutError) -> BuckyError {
1072 BuckyError::new(BuckyErrorCode::Timeout, format!("{}", err))
1073 }
1074}
1075
1076impl From<u32> for BuckyError {
1077 fn from(err: u32) -> BuckyError {
1078 BuckyError {
1079 code: BuckyErrorCode::CodeError,
1080 msg: format!("base_code_error: {}", err),
1081 origin: Some(BuckyOriginError::CodeError(err)),
1082 }
1083 }
1084}
1085
1086pub struct CodeError(pub u32, pub String);
1087
1088impl From<CodeError> for BuckyError {
1089 fn from(err: CodeError) -> Self {
1090 BuckyError {
1091 code: BuckyErrorCode::CodeError,
1092 msg: err.1,
1093 origin: Some(BuckyOriginError::CodeError(err.0)),
1094 }
1095 }
1096}
1097
1098#[cfg(not(target_arch = "wasm32"))]
1099impl From<rusqlite::Error> for BuckyError {
1100 fn from(err: rusqlite::Error) -> BuckyError {
1101 BuckyError {
1102 code: BuckyErrorCode::SqliteError,
1103 msg: format!("sqlite_error: {}", err),
1104 origin: Some(BuckyOriginError::SqliteError(err)),
1105 }
1106 }
1107}
1108#[cfg(feature = "sqlx-error")]
1109impl From<sqlx::Error> for BuckyError {
1110 fn from(err: sqlx::Error) -> Self {
1111 Self {
1112 code: BuckyErrorCode::SqliteError,
1113 msg: format!("sqlx error: {}", err),
1114 origin: Some(BuckyOriginError::SqlxError(err))
1115 }
1116 }
1117}
1118
1119impl From<serde_json::error::Error> for BuckyError {
1120 fn from(e: serde_json::error::Error) -> Self {
1121 BuckyError {
1122 code: BuckyErrorCode::JsonError,
1123 msg: format!("json_error: {}", e),
1124 origin: Some(BuckyOriginError::SerdeJsonError(e)),
1125 }
1126 }
1127}
1128
1129impl From<http_types::StatusCode> for BuckyError {
1130 fn from(code: http_types::StatusCode) -> Self {
1131 BuckyError {
1132 code: BuckyErrorCode::HttpError,
1133 msg: format!("http status code: {}", code),
1134 origin: Some(BuckyOriginError::HttpStatusCodeError(code)),
1135 }
1136 }
1137}
1138
1139impl From<url::ParseError> for BuckyError {
1140 fn from(e: url::ParseError) -> Self {
1141 BuckyError {
1142 code: BuckyErrorCode::UrlError,
1143 msg: format!("url_error: {}", e),
1144 origin: Some(BuckyOriginError::UrlError(e)),
1145 }
1146 }
1147}
1148
1149#[cfg(not(target_arch = "wasm32"))]
1150impl From<zip::result::ZipError> for BuckyError {
1151 fn from(e: zip::result::ZipError) -> Self {
1152 BuckyError {
1153 code: BuckyErrorCode::ZipError,
1154 msg: format!("zip_error: {:?}", e),
1155 origin: Some(BuckyOriginError::ZipError(e)),
1156 }
1157 }
1158}
1159
1160impl From<hex::FromHexError> for BuckyError {
1161 fn from(e: hex::FromHexError) -> Self {
1162 BuckyError {
1163 code: BuckyErrorCode::HexError,
1164 msg: format!("hex error: {}", e),
1165 origin: Some(BuckyOriginError::HexError(e)),
1166 }
1167 }
1168}
1169
1170impl From<rsa::errors::Error> for BuckyError {
1171 fn from(e: rsa::errors::Error) -> Self {
1172 BuckyError {
1173 code: BuckyErrorCode::RsaError,
1174 msg: format!("rsa error: {:?}", e),
1175 origin: Some(BuckyOriginError::RsaError(e)),
1176 }
1177 }
1178}
1179
1180impl From<BuckyErrorCode> for BuckyError {
1181 fn from(code: BuckyErrorCode) -> BuckyError {
1182 BuckyError {
1183 code,
1184 msg: "".to_owned(),
1185 origin: None,
1186 }
1187 }
1188}
1189
1190impl From<&str> for BuckyError {
1191 fn from(msg: &str) -> BuckyError {
1192 BuckyError {
1193 code: BuckyErrorCode::Unknown,
1194 msg: msg.to_owned(),
1195 origin: None,
1196 }
1197 }
1198}
1199
1200impl From<String> for BuckyError {
1201 fn from(msg: String) -> BuckyError {
1202 BuckyError {
1203 code: BuckyErrorCode::Unknown,
1204 msg,
1205 origin: None,
1206 }
1207 }
1208}
1209
1210impl From<(BuckyErrorCode, &str)> for BuckyError {
1211 fn from(cm: (BuckyErrorCode, &str)) -> BuckyError {
1212 BuckyError {
1213 code: cm.0,
1214 msg: cm.1.to_owned(),
1215 origin: None,
1216 }
1217 }
1218}
1219
1220impl From<(BuckyErrorCode, String)> for BuckyError {
1221 fn from(cm: (BuckyErrorCode, String)) -> BuckyError {
1222 BuckyError {
1223 code: cm.0,
1224 msg: cm.1,
1225 origin: None,
1226 }
1227 }
1228}
1229
1230impl From<Box<dyn Error>> for BuckyError {
1253 fn from(err: Box<dyn Error>) -> BuckyError {
1254 if err.is::<BuckyError>() {
1255 let be = err.downcast::<BuckyError>().unwrap();
1256 *be
1257 } else {
1258 BuckyError {
1259 code: BuckyErrorCode::Unknown,
1260 msg: format!("{}", err),
1261 origin: None,
1262 }
1263 }
1264 }
1265}
1266
1267impl Into<BuckyErrorCode> for BuckyError {
1268 fn into(self) -> BuckyErrorCode {
1269 self.code
1270 }
1271}
1272
1273impl Into<ErrorKind> for BuckyErrorCode {
1274 fn into(self) -> ErrorKind {
1275 match self {
1276 Self::Reject | Self::PermissionDenied => ErrorKind::PermissionDenied,
1277 Self::NotFound => ErrorKind::NotFound,
1278
1279 Self::ConnectionReset => ErrorKind::ConnectionReset,
1280 Self::ConnectionRefused => ErrorKind::ConnectionRefused,
1281 Self::ConnectionAborted => ErrorKind::ConnectionAborted,
1282 Self::AddrInUse => ErrorKind::AddrInUse,
1283 Self::AddrNotAvailable => ErrorKind::AddrNotAvailable,
1284 Self::NotConnected => ErrorKind::NotConnected,
1285 Self::AlreadyExists => ErrorKind::AlreadyExists,
1286 Self::Interrupted => ErrorKind::Interrupted,
1287 Self::WriteZero => ErrorKind::WriteZero,
1288 Self::UnexpectedEof => ErrorKind::UnexpectedEof,
1289 Self::UnSupport => ErrorKind::Unsupported,
1290 Self::BrokenPipe => ErrorKind::BrokenPipe,
1291 Self::WouldBlock => ErrorKind::WouldBlock,
1292 Self::Timeout => ErrorKind::TimedOut,
1293 Self::OutOfLimit => ErrorKind::OutOfMemory,
1294
1295 _ => ErrorKind::Other,
1296 }
1297 }
1298}
1299#[cfg(test)]
1307mod tests {
1308 use crate::*;
1309 use serde::{Deserialize, Serialize};
1310
1311 #[derive(Debug, Eq, PartialEq, Serialize, Deserialize)]
1312 struct SimpleBuckyError {
1313 msg: String,
1314 code: BuckyErrorCode,
1315 }
1316
1317 fn re_error() -> BuckyError {
1318 BuckyError::from(BuckyErrorCode::Failed)
1319 }
1320
1321 fn re_error2() -> BuckyError {
1322 BuckyError::from(format!("test error"))
1323 }
1324
1325 #[test]
1326 fn test_codec() {
1327 let code = BuckyErrorCode::ErrorState;
1328 let v = serde_json::to_string(&code).unwrap();
1329 println!("error code: {}", v);
1330 let code2: BuckyErrorCode = serde_json::from_str(&v).unwrap();
1331 assert_eq!(code2, code);
1332
1333 let e = SimpleBuckyError {
1334 code: BuckyErrorCode::InvalidFormat,
1335 msg: "test".to_owned(),
1336 };
1337 let v = serde_json::to_string(&e).unwrap();
1338 println!("error: {}", v);
1339 let e2: SimpleBuckyError = serde_json::from_str(&v).unwrap();
1340 assert_eq!(e, e2);
1341 }
1342
1343 #[test]
1344 fn test_error() {
1345 let err = re_error();
1346 assert!(err.code() == BuckyErrorCode::Failed);
1347
1348 re_error2();
1349
1350 let user_error = 101;
1351 let code = BuckyErrorCode::DecError(user_error);
1352 let value: u16 = code.into();
1353 let code2 = BuckyErrorCode::from(value);
1354 assert_eq!(code, code2);
1355
1356 let user_error = u16::MAX;
1357 let code = BuckyErrorCode::DecError(user_error);
1358 let value: u16 = code.into();
1359 let code2 = BuckyErrorCode::from(value);
1360 assert_ne!(code, code2);
1361 let max_code = BuckyErrorCode::DecError(BUCKY_DEC_ERROR_CODE_MAX);
1362 assert_eq!(max_code, code2);
1363
1364 let code = BuckyErrorCode::Unknown;
1365 let value: u16 = code.into();
1366 let code2 = BuckyErrorCode::from(value);
1367 assert_eq!(code, code2);
1368 }
1369
1370
1371 #[test]
1372 fn test_io_error() {
1373 let err = BuckyError::new(BuckyErrorCode::AddrInUse, "invaid address");
1374 assert!(err.code() == BuckyErrorCode::AddrInUse);
1375
1376 let e = BuckyError::bucky_error_to_io_error(err.clone());
1377 let be = BuckyError::io_error_to_bucky_error(e);
1378 assert_eq!(be.code(), err.code());
1379 assert_eq!(be.msg(), err.msg());
1380
1381 let e: std::io::Error = err.clone().into();
1382 let be: BuckyError = e.into();
1383
1384 assert_eq!(be.code(), err.code());
1385 assert_eq!(be.msg(), err.msg());
1386 }
1387}