1use core::{
4 convert::TryFrom,
5 fmt::{self, Debug, Formatter},
6};
7
8use crate::{
9 account::{
10 AddKeyFailure, RemoveKeyFailure, SetThresholdFailure, TryFromIntError,
11 TryFromSliceForAccountHashError, UpdateKeyFailure,
12 },
13 bytesrepr, contracts,
14 system::{auction, handle_payment, mint},
15 CLValueError,
16};
17
18const RESERVED_ERROR_MAX: u32 = u16::MAX as u32; const POS_ERROR_OFFSET: u32 = RESERVED_ERROR_MAX - u8::MAX as u32; const MINT_ERROR_OFFSET: u32 = (POS_ERROR_OFFSET - 1) - u8::MAX as u32; const HEADER_ERROR_OFFSET: u32 = (MINT_ERROR_OFFSET - 1) - u8::MAX as u32; const AUCTION_ERROR_OFFSET: u32 = (HEADER_ERROR_OFFSET - 1) - u8::MAX as u32; const USER_ERROR_MIN: u32 = RESERVED_ERROR_MAX + 1;
36
37const USER_ERROR_MAX: u32 = 2 * RESERVED_ERROR_MAX + 1;
39
40const MINT_ERROR_MIN: u32 = MINT_ERROR_OFFSET;
42
43const MINT_ERROR_MAX: u32 = POS_ERROR_OFFSET - 1;
45
46const HP_ERROR_MIN: u32 = POS_ERROR_OFFSET;
48
49const HP_ERROR_MAX: u32 = RESERVED_ERROR_MAX;
51
52const HEADER_ERROR_MIN: u32 = HEADER_ERROR_OFFSET;
54
55const HEADER_ERROR_MAX: u32 = HEADER_ERROR_OFFSET + u8::MAX as u32;
57
58const AUCTION_ERROR_MIN: u32 = AUCTION_ERROR_OFFSET;
60
61const AUCTION_ERROR_MAX: u32 = AUCTION_ERROR_OFFSET + u8::MAX as u32;
63
64#[derive(Copy, Clone, PartialEq, Eq)]
104#[non_exhaustive]
105pub enum ApiError {
106 None,
112 MissingArgument,
118 InvalidArgument,
124 Deserialize,
130 Read,
136 ValueNotFound,
142 ContractNotFound,
148 GetKey,
154 UnexpectedKeyVariant,
160 UnexpectedContractRefVariant, InvalidPurseName,
172 InvalidPurse,
178 UpgradeContractAtURef,
184 Transfer,
190 NoAccessRights,
196 CLTypeMismatch,
202 EarlyEndOfStream,
208 Formatting,
214 LeftOverBytes,
220 OutOfMemory,
226 MaxKeysLimit,
233 DuplicateKey,
240 PermissionDenied,
246 MissingKey,
253 ThresholdViolation,
261 KeyManagementThreshold,
268 DeploymentThreshold,
274 InsufficientTotalWeight,
281 InvalidSystemContract,
287 PurseNotCreated,
293 Unhandled,
299 BufferTooSmall,
305 HostBufferEmpty,
311 HostBufferFull,
317 AllocLayout,
323 DictionaryItemKeyExceedsLength,
329 InvalidDictionaryItemKey,
335 MissingSystemContractHash,
341 ExceededRecursionDepth,
347 NonRepresentableSerialization,
353 AuctionError(u8),
362 ContractHeader(u8),
371 Mint(u8),
380 HandlePayment(u8),
389 User(u16),
398}
399
400impl From<bytesrepr::Error> for ApiError {
401 fn from(error: bytesrepr::Error) -> Self {
402 match error {
403 bytesrepr::Error::EarlyEndOfStream => ApiError::EarlyEndOfStream,
404 bytesrepr::Error::Formatting => ApiError::Formatting,
405 bytesrepr::Error::LeftOverBytes => ApiError::LeftOverBytes,
406 bytesrepr::Error::OutOfMemory => ApiError::OutOfMemory,
407 bytesrepr::Error::NotRepresentable => ApiError::NonRepresentableSerialization,
408 bytesrepr::Error::ExceededRecursionDepth => ApiError::ExceededRecursionDepth,
409 }
410 }
411}
412
413impl From<AddKeyFailure> for ApiError {
414 fn from(error: AddKeyFailure) -> Self {
415 match error {
416 AddKeyFailure::MaxKeysLimit => ApiError::MaxKeysLimit,
417 AddKeyFailure::DuplicateKey => ApiError::DuplicateKey,
418 AddKeyFailure::PermissionDenied => ApiError::PermissionDenied,
419 }
420 }
421}
422
423impl From<UpdateKeyFailure> for ApiError {
424 fn from(error: UpdateKeyFailure) -> Self {
425 match error {
426 UpdateKeyFailure::MissingKey => ApiError::MissingKey,
427 UpdateKeyFailure::PermissionDenied => ApiError::PermissionDenied,
428 UpdateKeyFailure::ThresholdViolation => ApiError::ThresholdViolation,
429 }
430 }
431}
432
433impl From<RemoveKeyFailure> for ApiError {
434 fn from(error: RemoveKeyFailure) -> Self {
435 match error {
436 RemoveKeyFailure::MissingKey => ApiError::MissingKey,
437 RemoveKeyFailure::PermissionDenied => ApiError::PermissionDenied,
438 RemoveKeyFailure::ThresholdViolation => ApiError::ThresholdViolation,
439 }
440 }
441}
442
443impl From<SetThresholdFailure> for ApiError {
444 fn from(error: SetThresholdFailure) -> Self {
445 match error {
446 SetThresholdFailure::KeyManagementThreshold => ApiError::KeyManagementThreshold,
447 SetThresholdFailure::DeploymentThreshold => ApiError::DeploymentThreshold,
448 SetThresholdFailure::PermissionDeniedError => ApiError::PermissionDenied,
449 SetThresholdFailure::InsufficientTotalWeight => ApiError::InsufficientTotalWeight,
450 }
451 }
452}
453
454impl From<CLValueError> for ApiError {
455 fn from(error: CLValueError) -> Self {
456 match error {
457 CLValueError::Serialization(bytesrepr_error) => bytesrepr_error.into(),
458 CLValueError::Type(_) => ApiError::CLTypeMismatch,
459 }
460 }
461}
462
463impl From<contracts::Error> for ApiError {
464 fn from(error: contracts::Error) -> Self {
465 ApiError::ContractHeader(error as u8)
466 }
467}
468
469impl From<auction::Error> for ApiError {
470 fn from(error: auction::Error) -> Self {
471 ApiError::AuctionError(error as u8)
472 }
473}
474
475#[doc(hidden)]
477impl From<TryFromIntError> for ApiError {
478 fn from(_error: TryFromIntError) -> Self {
479 ApiError::Unhandled
480 }
481}
482
483impl From<TryFromSliceForAccountHashError> for ApiError {
484 fn from(_error: TryFromSliceForAccountHashError) -> Self {
485 ApiError::Deserialize
486 }
487}
488
489impl From<mint::Error> for ApiError {
490 fn from(error: mint::Error) -> Self {
491 ApiError::Mint(error as u8)
492 }
493}
494
495impl From<handle_payment::Error> for ApiError {
496 fn from(error: handle_payment::Error) -> Self {
497 ApiError::HandlePayment(error as u8)
498 }
499}
500
501impl From<ApiError> for u32 {
502 fn from(error: ApiError) -> Self {
503 match error {
504 ApiError::None => 1,
505 ApiError::MissingArgument => 2,
506 ApiError::InvalidArgument => 3,
507 ApiError::Deserialize => 4,
508 ApiError::Read => 5,
509 ApiError::ValueNotFound => 6,
510 ApiError::ContractNotFound => 7,
511 ApiError::GetKey => 8,
512 ApiError::UnexpectedKeyVariant => 9,
513 ApiError::UnexpectedContractRefVariant => 10,
514 ApiError::InvalidPurseName => 11,
515 ApiError::InvalidPurse => 12,
516 ApiError::UpgradeContractAtURef => 13,
517 ApiError::Transfer => 14,
518 ApiError::NoAccessRights => 15,
519 ApiError::CLTypeMismatch => 16,
520 ApiError::EarlyEndOfStream => 17,
521 ApiError::Formatting => 18,
522 ApiError::LeftOverBytes => 19,
523 ApiError::OutOfMemory => 20,
524 ApiError::MaxKeysLimit => 21,
525 ApiError::DuplicateKey => 22,
526 ApiError::PermissionDenied => 23,
527 ApiError::MissingKey => 24,
528 ApiError::ThresholdViolation => 25,
529 ApiError::KeyManagementThreshold => 26,
530 ApiError::DeploymentThreshold => 27,
531 ApiError::InsufficientTotalWeight => 28,
532 ApiError::InvalidSystemContract => 29,
533 ApiError::PurseNotCreated => 30,
534 ApiError::Unhandled => 31,
535 ApiError::BufferTooSmall => 32,
536 ApiError::HostBufferEmpty => 33,
537 ApiError::HostBufferFull => 34,
538 ApiError::AllocLayout => 35,
539 ApiError::DictionaryItemKeyExceedsLength => 36,
540 ApiError::InvalidDictionaryItemKey => 37,
541 ApiError::MissingSystemContractHash => 38,
542 ApiError::ExceededRecursionDepth => 39,
543 ApiError::NonRepresentableSerialization => 40,
544 ApiError::AuctionError(value) => AUCTION_ERROR_OFFSET + u32::from(value),
545 ApiError::ContractHeader(value) => HEADER_ERROR_OFFSET + u32::from(value),
546 ApiError::Mint(value) => MINT_ERROR_OFFSET + u32::from(value),
547 ApiError::HandlePayment(value) => POS_ERROR_OFFSET + u32::from(value),
548 ApiError::User(value) => RESERVED_ERROR_MAX + 1 + u32::from(value),
549 }
550 }
551}
552
553impl From<u32> for ApiError {
554 fn from(value: u32) -> ApiError {
555 match value {
556 1 => ApiError::None,
557 2 => ApiError::MissingArgument,
558 3 => ApiError::InvalidArgument,
559 4 => ApiError::Deserialize,
560 5 => ApiError::Read,
561 6 => ApiError::ValueNotFound,
562 7 => ApiError::ContractNotFound,
563 8 => ApiError::GetKey,
564 9 => ApiError::UnexpectedKeyVariant,
565 10 => ApiError::UnexpectedContractRefVariant,
566 11 => ApiError::InvalidPurseName,
567 12 => ApiError::InvalidPurse,
568 13 => ApiError::UpgradeContractAtURef,
569 14 => ApiError::Transfer,
570 15 => ApiError::NoAccessRights,
571 16 => ApiError::CLTypeMismatch,
572 17 => ApiError::EarlyEndOfStream,
573 18 => ApiError::Formatting,
574 19 => ApiError::LeftOverBytes,
575 20 => ApiError::OutOfMemory,
576 21 => ApiError::MaxKeysLimit,
577 22 => ApiError::DuplicateKey,
578 23 => ApiError::PermissionDenied,
579 24 => ApiError::MissingKey,
580 25 => ApiError::ThresholdViolation,
581 26 => ApiError::KeyManagementThreshold,
582 27 => ApiError::DeploymentThreshold,
583 28 => ApiError::InsufficientTotalWeight,
584 29 => ApiError::InvalidSystemContract,
585 30 => ApiError::PurseNotCreated,
586 31 => ApiError::Unhandled,
587 32 => ApiError::BufferTooSmall,
588 33 => ApiError::HostBufferEmpty,
589 34 => ApiError::HostBufferFull,
590 35 => ApiError::AllocLayout,
591 36 => ApiError::DictionaryItemKeyExceedsLength,
592 37 => ApiError::InvalidDictionaryItemKey,
593 38 => ApiError::MissingSystemContractHash,
594 39 => ApiError::ExceededRecursionDepth,
595 40 => ApiError::NonRepresentableSerialization,
596 USER_ERROR_MIN..=USER_ERROR_MAX => ApiError::User(value as u16),
597 HP_ERROR_MIN..=HP_ERROR_MAX => ApiError::HandlePayment(value as u8),
598 MINT_ERROR_MIN..=MINT_ERROR_MAX => ApiError::Mint(value as u8),
599 HEADER_ERROR_MIN..=HEADER_ERROR_MAX => ApiError::ContractHeader(value as u8),
600 AUCTION_ERROR_MIN..=AUCTION_ERROR_MAX => ApiError::AuctionError(value as u8),
601 _ => ApiError::Unhandled,
602 }
603 }
604}
605
606impl Debug for ApiError {
607 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
608 match self {
609 ApiError::None => write!(f, "ApiError::None")?,
610 ApiError::MissingArgument => write!(f, "ApiError::MissingArgument")?,
611 ApiError::InvalidArgument => write!(f, "ApiError::InvalidArgument")?,
612 ApiError::Deserialize => write!(f, "ApiError::Deserialize")?,
613 ApiError::Read => write!(f, "ApiError::Read")?,
614 ApiError::ValueNotFound => write!(f, "ApiError::ValueNotFound")?,
615 ApiError::ContractNotFound => write!(f, "ApiError::ContractNotFound")?,
616 ApiError::GetKey => write!(f, "ApiError::GetKey")?,
617 ApiError::UnexpectedKeyVariant => write!(f, "ApiError::UnexpectedKeyVariant")?,
618 ApiError::UnexpectedContractRefVariant => {
619 write!(f, "ApiError::UnexpectedContractRefVariant")?
620 }
621 ApiError::InvalidPurseName => write!(f, "ApiError::InvalidPurseName")?,
622 ApiError::InvalidPurse => write!(f, "ApiError::InvalidPurse")?,
623 ApiError::UpgradeContractAtURef => write!(f, "ApiError::UpgradeContractAtURef")?,
624 ApiError::Transfer => write!(f, "ApiError::Transfer")?,
625 ApiError::NoAccessRights => write!(f, "ApiError::NoAccessRights")?,
626 ApiError::CLTypeMismatch => write!(f, "ApiError::CLTypeMismatch")?,
627 ApiError::EarlyEndOfStream => write!(f, "ApiError::EarlyEndOfStream")?,
628 ApiError::Formatting => write!(f, "ApiError::Formatting")?,
629 ApiError::LeftOverBytes => write!(f, "ApiError::LeftOverBytes")?,
630 ApiError::OutOfMemory => write!(f, "ApiError::OutOfMemory")?,
631 ApiError::MaxKeysLimit => write!(f, "ApiError::MaxKeysLimit")?,
632 ApiError::DuplicateKey => write!(f, "ApiError::DuplicateKey")?,
633 ApiError::PermissionDenied => write!(f, "ApiError::PermissionDenied")?,
634 ApiError::MissingKey => write!(f, "ApiError::MissingKey")?,
635 ApiError::ThresholdViolation => write!(f, "ApiError::ThresholdViolation")?,
636 ApiError::KeyManagementThreshold => write!(f, "ApiError::KeyManagementThreshold")?,
637 ApiError::DeploymentThreshold => write!(f, "ApiError::DeploymentThreshold")?,
638 ApiError::InsufficientTotalWeight => write!(f, "ApiError::InsufficientTotalWeight")?,
639 ApiError::InvalidSystemContract => write!(f, "ApiError::InvalidSystemContract")?,
640 ApiError::PurseNotCreated => write!(f, "ApiError::PurseNotCreated")?,
641 ApiError::Unhandled => write!(f, "ApiError::Unhandled")?,
642 ApiError::BufferTooSmall => write!(f, "ApiError::BufferTooSmall")?,
643 ApiError::HostBufferEmpty => write!(f, "ApiError::HostBufferEmpty")?,
644 ApiError::HostBufferFull => write!(f, "ApiError::HostBufferFull")?,
645 ApiError::AllocLayout => write!(f, "ApiError::AllocLayout")?,
646 ApiError::DictionaryItemKeyExceedsLength => {
647 write!(f, "ApiError::DictionaryItemKeyTooLarge")?
648 }
649 ApiError::InvalidDictionaryItemKey => write!(f, "ApiError::InvalidDictionaryItemKey")?,
650 ApiError::MissingSystemContractHash => write!(f, "ApiError::MissingContractHash")?,
651 ApiError::NonRepresentableSerialization => {
652 write!(f, "ApiError::NonRepresentableSerialization")?
653 }
654 ApiError::ExceededRecursionDepth => write!(f, "ApiError::ExceededRecursionDepth")?,
655 ApiError::AuctionError(value) => write!(
656 f,
657 "ApiError::AuctionError({:?})",
658 auction::Error::try_from(*value).map_err(|_err| fmt::Error)?
659 )?,
660 ApiError::ContractHeader(value) => write!(
661 f,
662 "ApiError::ContractHeader({:?})",
663 contracts::Error::try_from(*value).map_err(|_err| fmt::Error)?
664 )?,
665 ApiError::Mint(value) => write!(
666 f,
667 "ApiError::Mint({:?})",
668 mint::Error::try_from(*value).map_err(|_err| fmt::Error)?
669 )?,
670 ApiError::HandlePayment(value) => write!(
671 f,
672 "ApiError::HandlePayment({:?})",
673 handle_payment::Error::try_from(*value).map_err(|_err| fmt::Error)?
674 )?,
675 ApiError::User(value) => write!(f, "ApiError::User({})", value)?,
676 }
677 write!(f, " [{}]", u32::from(*self))
678 }
679}
680
681impl fmt::Display for ApiError {
682 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
683 match self {
684 ApiError::User(value) => write!(f, "User error: {}", value),
685 ApiError::ContractHeader(value) => write!(f, "Contract header error: {}", value),
686 ApiError::Mint(value) => write!(f, "Mint error: {}", value),
687 ApiError::HandlePayment(value) => write!(f, "Handle Payment error: {}", value),
688 _ => <Self as Debug>::fmt(self, f),
689 }
690 }
691}
692
693#[doc(hidden)]
695pub fn i32_from<T>(result: Result<(), T>) -> i32
696where
697 ApiError: From<T>,
698{
699 match result {
700 Ok(()) => 0,
701 Err(error) => {
702 let api_error = ApiError::from(error);
703 u32::from(api_error) as i32
704 }
705 }
706}
707
708pub fn result_from(value: i32) -> Result<(), ApiError> {
712 match value {
713 0 => Ok(()),
714 _ => Err(ApiError::from(value as u32)),
715 }
716}
717
718#[cfg(test)]
719mod tests {
720 use std::{i32, u16, u8};
721
722 use super::*;
723
724 fn round_trip(result: Result<(), ApiError>) {
725 let code = i32_from(result);
726 assert_eq!(result, result_from(code));
727 }
728
729 #[test]
730 fn error_values() {
731 assert_eq!(65_024_u32, u32::from(ApiError::Mint(0))); assert_eq!(65_279_u32, u32::from(ApiError::Mint(u8::MAX)));
733 assert_eq!(65_280_u32, u32::from(ApiError::HandlePayment(0))); assert_eq!(65_535_u32, u32::from(ApiError::HandlePayment(u8::MAX)));
735 assert_eq!(65_536_u32, u32::from(ApiError::User(0))); assert_eq!(131_071_u32, u32::from(ApiError::User(u16::MAX))); }
738
739 #[test]
740 fn error_descriptions_getkey() {
741 assert_eq!("ApiError::GetKey [8]", &format!("{:?}", ApiError::GetKey));
742 assert_eq!("ApiError::GetKey [8]", &format!("{}", ApiError::GetKey));
743 }
744
745 #[test]
746 fn error_descriptions_contract_header() {
747 assert_eq!(
748 "ApiError::ContractHeader(PreviouslyUsedVersion) [64769]",
749 &format!(
750 "{:?}",
751 ApiError::ContractHeader(contracts::Error::PreviouslyUsedVersion as u8)
752 )
753 );
754 assert_eq!(
755 "Contract header error: 0",
756 &format!("{}", ApiError::ContractHeader(0))
757 );
758 assert_eq!(
759 "Contract header error: 255",
760 &format!("{}", ApiError::ContractHeader(u8::MAX))
761 );
762 }
763
764 #[test]
765 fn error_descriptions_mint() {
766 assert_eq!(
767 "ApiError::Mint(InsufficientFunds) [65024]",
768 &format!("{:?}", ApiError::Mint(0))
769 );
770 assert_eq!("Mint error: 0", &format!("{}", ApiError::Mint(0)));
771 assert_eq!("Mint error: 255", &format!("{}", ApiError::Mint(u8::MAX)));
772 }
773
774 #[test]
775 fn error_descriptions_handle_payment() {
776 assert_eq!(
777 "ApiError::HandlePayment(NotBonded) [65280]",
778 &format!(
779 "{:?}",
780 ApiError::HandlePayment(handle_payment::Error::NotBonded as u8)
781 )
782 );
783 }
784 #[test]
785 fn error_descriptions_handle_payment_display() {
786 assert_eq!(
787 "Handle Payment error: 0",
788 &format!(
789 "{}",
790 ApiError::HandlePayment(handle_payment::Error::NotBonded as u8)
791 )
792 );
793 }
794
795 #[test]
796 fn error_descriptions_user_errors() {
797 assert_eq!(
798 "ApiError::User(0) [65536]",
799 &format!("{:?}", ApiError::User(0))
800 );
801
802 assert_eq!("User error: 0", &format!("{}", ApiError::User(0)));
803 assert_eq!(
804 "ApiError::User(65535) [131071]",
805 &format!("{:?}", ApiError::User(u16::MAX))
806 );
807 assert_eq!(
808 "User error: 65535",
809 &format!("{}", ApiError::User(u16::MAX))
810 );
811 }
812
813 #[test]
814 fn error_edge_cases() {
815 assert_eq!(Err(ApiError::Unhandled), result_from(i32::MAX));
816 assert_eq!(
817 Err(ApiError::ContractHeader(255)),
818 result_from(MINT_ERROR_OFFSET as i32 - 1)
819 );
820 assert_eq!(Err(ApiError::Unhandled), result_from(-1));
821 assert_eq!(Err(ApiError::Unhandled), result_from(i32::MIN));
822 }
823
824 #[test]
825 fn error_round_trips() {
826 round_trip(Ok(()));
827 round_trip(Err(ApiError::None));
828 round_trip(Err(ApiError::MissingArgument));
829 round_trip(Err(ApiError::InvalidArgument));
830 round_trip(Err(ApiError::Deserialize));
831 round_trip(Err(ApiError::Read));
832 round_trip(Err(ApiError::ValueNotFound));
833 round_trip(Err(ApiError::ContractNotFound));
834 round_trip(Err(ApiError::GetKey));
835 round_trip(Err(ApiError::UnexpectedKeyVariant));
836 round_trip(Err(ApiError::UnexpectedContractRefVariant));
837 round_trip(Err(ApiError::InvalidPurseName));
838 round_trip(Err(ApiError::InvalidPurse));
839 round_trip(Err(ApiError::UpgradeContractAtURef));
840 round_trip(Err(ApiError::Transfer));
841 round_trip(Err(ApiError::NoAccessRights));
842 round_trip(Err(ApiError::CLTypeMismatch));
843 round_trip(Err(ApiError::EarlyEndOfStream));
844 round_trip(Err(ApiError::Formatting));
845 round_trip(Err(ApiError::LeftOverBytes));
846 round_trip(Err(ApiError::OutOfMemory));
847 round_trip(Err(ApiError::MaxKeysLimit));
848 round_trip(Err(ApiError::DuplicateKey));
849 round_trip(Err(ApiError::PermissionDenied));
850 round_trip(Err(ApiError::MissingKey));
851 round_trip(Err(ApiError::ThresholdViolation));
852 round_trip(Err(ApiError::KeyManagementThreshold));
853 round_trip(Err(ApiError::DeploymentThreshold));
854 round_trip(Err(ApiError::InsufficientTotalWeight));
855 round_trip(Err(ApiError::InvalidSystemContract));
856 round_trip(Err(ApiError::PurseNotCreated));
857 round_trip(Err(ApiError::Unhandled));
858 round_trip(Err(ApiError::BufferTooSmall));
859 round_trip(Err(ApiError::HostBufferEmpty));
860 round_trip(Err(ApiError::HostBufferFull));
861 round_trip(Err(ApiError::AllocLayout));
862 round_trip(Err(ApiError::NonRepresentableSerialization));
863 round_trip(Err(ApiError::ContractHeader(0)));
864 round_trip(Err(ApiError::ContractHeader(u8::MAX)));
865 round_trip(Err(ApiError::Mint(0)));
866 round_trip(Err(ApiError::Mint(u8::MAX)));
867 round_trip(Err(ApiError::HandlePayment(0)));
868 round_trip(Err(ApiError::HandlePayment(u8::MAX)));
869 round_trip(Err(ApiError::User(0)));
870 round_trip(Err(ApiError::User(u16::MAX)));
871 round_trip(Err(ApiError::AuctionError(0)));
872 round_trip(Err(ApiError::AuctionError(u8::MAX)));
873 }
874}