1use core::{
4 convert::TryFrom,
5 fmt::{self, Debug, Formatter},
6};
7
8use crate::{
9 account::{
10 AddKeyFailure, RemoveKeyFailure, SetThresholdFailure, TryFromIntError, UpdateKeyFailure,
11 },
12 addressable_entity::{self, MessageTopicError, TryFromSliceForAccountHashError},
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,
166 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),
372 Mint(u8),
381 HandlePayment(u8),
390 User(u16),
399 MessageTopicAlreadyRegistered,
405 MaxTopicsNumberExceeded,
411 MaxTopicNameSizeExceeded,
417 MessageTopicNotRegistered,
423 MessageTopicFull,
429 MessageTooLarge,
435 MaxMessagesPerBlockExceeded,
442 NotAllowedToAddContractVersion,
449 InvalidDelegationAmountLimits,
455 InvalidCallerInfoRequest,
461}
462
463impl From<bytesrepr::Error> for ApiError {
464 fn from(error: bytesrepr::Error) -> Self {
465 match error {
466 bytesrepr::Error::EarlyEndOfStream => ApiError::EarlyEndOfStream,
467 bytesrepr::Error::Formatting => ApiError::Formatting,
468 bytesrepr::Error::LeftOverBytes => ApiError::LeftOverBytes,
469 bytesrepr::Error::OutOfMemory => ApiError::OutOfMemory,
470 bytesrepr::Error::NotRepresentable => ApiError::NonRepresentableSerialization,
471 bytesrepr::Error::ExceededRecursionDepth => ApiError::ExceededRecursionDepth,
472 }
473 }
474}
475
476impl From<AddKeyFailure> for ApiError {
477 fn from(error: AddKeyFailure) -> Self {
478 match error {
479 AddKeyFailure::MaxKeysLimit => ApiError::MaxKeysLimit,
480 AddKeyFailure::DuplicateKey => ApiError::DuplicateKey,
481 AddKeyFailure::PermissionDenied => ApiError::PermissionDenied,
482 }
483 }
484}
485
486impl From<UpdateKeyFailure> for ApiError {
487 fn from(error: UpdateKeyFailure) -> Self {
488 match error {
489 UpdateKeyFailure::MissingKey => ApiError::MissingKey,
490 UpdateKeyFailure::PermissionDenied => ApiError::PermissionDenied,
491 UpdateKeyFailure::ThresholdViolation => ApiError::ThresholdViolation,
492 }
493 }
494}
495
496impl From<RemoveKeyFailure> for ApiError {
497 fn from(error: RemoveKeyFailure) -> Self {
498 match error {
499 RemoveKeyFailure::MissingKey => ApiError::MissingKey,
500 RemoveKeyFailure::PermissionDenied => ApiError::PermissionDenied,
501 RemoveKeyFailure::ThresholdViolation => ApiError::ThresholdViolation,
502 }
503 }
504}
505
506impl From<SetThresholdFailure> for ApiError {
507 fn from(error: SetThresholdFailure) -> Self {
508 match error {
509 SetThresholdFailure::KeyManagementThreshold => ApiError::KeyManagementThreshold,
510 SetThresholdFailure::DeploymentThreshold => ApiError::DeploymentThreshold,
511 SetThresholdFailure::PermissionDeniedError => ApiError::PermissionDenied,
512 SetThresholdFailure::InsufficientTotalWeight => ApiError::InsufficientTotalWeight,
513 }
514 }
515}
516
517impl From<CLValueError> for ApiError {
518 fn from(error: CLValueError) -> Self {
519 match error {
520 CLValueError::Serialization(bytesrepr_error) => bytesrepr_error.into(),
521 CLValueError::Type(_) => ApiError::CLTypeMismatch,
522 }
523 }
524}
525
526impl From<addressable_entity::Error> for ApiError {
527 fn from(error: addressable_entity::Error) -> Self {
528 ApiError::ContractHeader(error as u8)
529 }
530}
531
532impl From<contracts::Error> for ApiError {
533 fn from(error: contracts::Error) -> Self {
534 ApiError::ContractHeader(error as u8)
535 }
536}
537
538impl From<auction::Error> for ApiError {
539 fn from(error: auction::Error) -> Self {
540 ApiError::AuctionError(error as u8)
541 }
542}
543
544#[doc(hidden)]
546impl From<TryFromIntError> for ApiError {
547 fn from(_error: TryFromIntError) -> Self {
548 ApiError::Unhandled
549 }
550}
551
552impl From<TryFromSliceForAccountHashError> for ApiError {
553 fn from(_error: TryFromSliceForAccountHashError) -> Self {
554 ApiError::Deserialize
555 }
556}
557
558impl From<mint::Error> for ApiError {
559 fn from(error: mint::Error) -> Self {
560 ApiError::Mint(error as u8)
561 }
562}
563
564impl From<handle_payment::Error> for ApiError {
565 fn from(error: handle_payment::Error) -> Self {
566 ApiError::HandlePayment(error as u8)
567 }
568}
569
570impl From<MessageTopicError> for ApiError {
571 fn from(error: MessageTopicError) -> Self {
572 match error {
573 MessageTopicError::DuplicateTopic => ApiError::MessageTopicAlreadyRegistered,
574 MessageTopicError::MaxTopicsExceeded => ApiError::MaxTopicsNumberExceeded,
575 MessageTopicError::TopicNameSizeExceeded => ApiError::MaxTopicNameSizeExceeded,
576 }
577 }
578}
579
580impl From<ApiError> for u32 {
581 fn from(error: ApiError) -> Self {
582 match error {
583 ApiError::None => 1,
584 ApiError::MissingArgument => 2,
585 ApiError::InvalidArgument => 3,
586 ApiError::Deserialize => 4,
587 ApiError::Read => 5,
588 ApiError::ValueNotFound => 6,
589 ApiError::ContractNotFound => 7,
590 ApiError::GetKey => 8,
591 ApiError::UnexpectedKeyVariant => 9,
592 ApiError::UnexpectedContractRefVariant => 10,
593 ApiError::InvalidPurseName => 11,
594 ApiError::InvalidPurse => 12,
595 ApiError::UpgradeContractAtURef => 13,
596 ApiError::Transfer => 14,
597 ApiError::NoAccessRights => 15,
598 ApiError::CLTypeMismatch => 16,
599 ApiError::EarlyEndOfStream => 17,
600 ApiError::Formatting => 18,
601 ApiError::LeftOverBytes => 19,
602 ApiError::OutOfMemory => 20,
603 ApiError::MaxKeysLimit => 21,
604 ApiError::DuplicateKey => 22,
605 ApiError::PermissionDenied => 23,
606 ApiError::MissingKey => 24,
607 ApiError::ThresholdViolation => 25,
608 ApiError::KeyManagementThreshold => 26,
609 ApiError::DeploymentThreshold => 27,
610 ApiError::InsufficientTotalWeight => 28,
611 ApiError::InvalidSystemContract => 29,
612 ApiError::PurseNotCreated => 30,
613 ApiError::Unhandled => 31,
614 ApiError::BufferTooSmall => 32,
615 ApiError::HostBufferEmpty => 33,
616 ApiError::HostBufferFull => 34,
617 ApiError::AllocLayout => 35,
618 ApiError::DictionaryItemKeyExceedsLength => 36,
619 ApiError::InvalidDictionaryItemKey => 37,
620 ApiError::MissingSystemContractHash => 38,
621 ApiError::ExceededRecursionDepth => 39,
622 ApiError::NonRepresentableSerialization => 40,
623 ApiError::MessageTopicAlreadyRegistered => 41,
624 ApiError::MaxTopicsNumberExceeded => 42,
625 ApiError::MaxTopicNameSizeExceeded => 43,
626 ApiError::MessageTopicNotRegistered => 44,
627 ApiError::MessageTopicFull => 45,
628 ApiError::MessageTooLarge => 46,
629 ApiError::MaxMessagesPerBlockExceeded => 47,
630 ApiError::NotAllowedToAddContractVersion => 48,
631 ApiError::InvalidDelegationAmountLimits => 49,
632 ApiError::InvalidCallerInfoRequest => 50,
633 ApiError::AuctionError(value) => AUCTION_ERROR_OFFSET + u32::from(value),
634 ApiError::ContractHeader(value) => HEADER_ERROR_OFFSET + u32::from(value),
635 ApiError::Mint(value) => MINT_ERROR_OFFSET + u32::from(value),
636 ApiError::HandlePayment(value) => POS_ERROR_OFFSET + u32::from(value),
637 ApiError::User(value) => RESERVED_ERROR_MAX + 1 + u32::from(value),
638 }
639 }
640}
641
642impl From<u32> for ApiError {
643 fn from(value: u32) -> ApiError {
644 match value {
645 1 => ApiError::None,
646 2 => ApiError::MissingArgument,
647 3 => ApiError::InvalidArgument,
648 4 => ApiError::Deserialize,
649 5 => ApiError::Read,
650 6 => ApiError::ValueNotFound,
651 7 => ApiError::ContractNotFound,
652 8 => ApiError::GetKey,
653 9 => ApiError::UnexpectedKeyVariant,
654 10 => ApiError::UnexpectedContractRefVariant,
655 11 => ApiError::InvalidPurseName,
656 12 => ApiError::InvalidPurse,
657 13 => ApiError::UpgradeContractAtURef,
658 14 => ApiError::Transfer,
659 15 => ApiError::NoAccessRights,
660 16 => ApiError::CLTypeMismatch,
661 17 => ApiError::EarlyEndOfStream,
662 18 => ApiError::Formatting,
663 19 => ApiError::LeftOverBytes,
664 20 => ApiError::OutOfMemory,
665 21 => ApiError::MaxKeysLimit,
666 22 => ApiError::DuplicateKey,
667 23 => ApiError::PermissionDenied,
668 24 => ApiError::MissingKey,
669 25 => ApiError::ThresholdViolation,
670 26 => ApiError::KeyManagementThreshold,
671 27 => ApiError::DeploymentThreshold,
672 28 => ApiError::InsufficientTotalWeight,
673 29 => ApiError::InvalidSystemContract,
674 30 => ApiError::PurseNotCreated,
675 31 => ApiError::Unhandled,
676 32 => ApiError::BufferTooSmall,
677 33 => ApiError::HostBufferEmpty,
678 34 => ApiError::HostBufferFull,
679 35 => ApiError::AllocLayout,
680 36 => ApiError::DictionaryItemKeyExceedsLength,
681 37 => ApiError::InvalidDictionaryItemKey,
682 38 => ApiError::MissingSystemContractHash,
683 39 => ApiError::ExceededRecursionDepth,
684 40 => ApiError::NonRepresentableSerialization,
685 41 => ApiError::MessageTopicAlreadyRegistered,
686 42 => ApiError::MaxTopicsNumberExceeded,
687 43 => ApiError::MaxTopicNameSizeExceeded,
688 44 => ApiError::MessageTopicNotRegistered,
689 45 => ApiError::MessageTopicFull,
690 46 => ApiError::MessageTooLarge,
691 47 => ApiError::MaxMessagesPerBlockExceeded,
692 48 => ApiError::NotAllowedToAddContractVersion,
693 49 => ApiError::InvalidDelegationAmountLimits,
694 50 => ApiError::InvalidCallerInfoRequest,
695 USER_ERROR_MIN..=USER_ERROR_MAX => ApiError::User(value as u16),
696 HP_ERROR_MIN..=HP_ERROR_MAX => ApiError::HandlePayment(value as u8),
697 MINT_ERROR_MIN..=MINT_ERROR_MAX => ApiError::Mint(value as u8),
698 HEADER_ERROR_MIN..=HEADER_ERROR_MAX => ApiError::ContractHeader(value as u8),
699 AUCTION_ERROR_MIN..=AUCTION_ERROR_MAX => ApiError::AuctionError(value as u8),
700 _ => ApiError::Unhandled,
701 }
702 }
703}
704
705impl Debug for ApiError {
706 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
707 match self {
708 ApiError::None => write!(f, "ApiError::None")?,
709 ApiError::MissingArgument => write!(f, "ApiError::MissingArgument")?,
710 ApiError::InvalidArgument => write!(f, "ApiError::InvalidArgument")?,
711 ApiError::Deserialize => write!(f, "ApiError::Deserialize")?,
712 ApiError::Read => write!(f, "ApiError::Read")?,
713 ApiError::ValueNotFound => write!(f, "ApiError::ValueNotFound")?,
714 ApiError::ContractNotFound => write!(f, "ApiError::ContractNotFound")?,
715 ApiError::GetKey => write!(f, "ApiError::GetKey")?,
716 ApiError::UnexpectedKeyVariant => write!(f, "ApiError::UnexpectedKeyVariant")?,
717 ApiError::UnexpectedContractRefVariant => {
718 write!(f, "ApiError::UnexpectedContractRefVariant")?
719 }
720 ApiError::InvalidPurseName => write!(f, "ApiError::InvalidPurseName")?,
721 ApiError::InvalidPurse => write!(f, "ApiError::InvalidPurse")?,
722 ApiError::UpgradeContractAtURef => write!(f, "ApiError::UpgradeContractAtURef")?,
723 ApiError::Transfer => write!(f, "ApiError::Transfer")?,
724 ApiError::NoAccessRights => write!(f, "ApiError::NoAccessRights")?,
725 ApiError::CLTypeMismatch => write!(f, "ApiError::CLTypeMismatch")?,
726 ApiError::EarlyEndOfStream => write!(f, "ApiError::EarlyEndOfStream")?,
727 ApiError::Formatting => write!(f, "ApiError::Formatting")?,
728 ApiError::LeftOverBytes => write!(f, "ApiError::LeftOverBytes")?,
729 ApiError::OutOfMemory => write!(f, "ApiError::OutOfMemory")?,
730 ApiError::MaxKeysLimit => write!(f, "ApiError::MaxKeysLimit")?,
731 ApiError::DuplicateKey => write!(f, "ApiError::DuplicateKey")?,
732 ApiError::PermissionDenied => write!(f, "ApiError::PermissionDenied")?,
733 ApiError::MissingKey => write!(f, "ApiError::MissingKey")?,
734 ApiError::ThresholdViolation => write!(f, "ApiError::ThresholdViolation")?,
735 ApiError::KeyManagementThreshold => write!(f, "ApiError::KeyManagementThreshold")?,
736 ApiError::DeploymentThreshold => write!(f, "ApiError::DeploymentThreshold")?,
737 ApiError::InsufficientTotalWeight => write!(f, "ApiError::InsufficientTotalWeight")?,
738 ApiError::InvalidSystemContract => write!(f, "ApiError::InvalidSystemContract")?,
739 ApiError::PurseNotCreated => write!(f, "ApiError::PurseNotCreated")?,
740 ApiError::Unhandled => write!(f, "ApiError::Unhandled")?,
741 ApiError::BufferTooSmall => write!(f, "ApiError::BufferTooSmall")?,
742 ApiError::HostBufferEmpty => write!(f, "ApiError::HostBufferEmpty")?,
743 ApiError::HostBufferFull => write!(f, "ApiError::HostBufferFull")?,
744 ApiError::AllocLayout => write!(f, "ApiError::AllocLayout")?,
745 ApiError::DictionaryItemKeyExceedsLength => {
746 write!(f, "ApiError::DictionaryItemKeyTooLarge")?
747 }
748 ApiError::InvalidDictionaryItemKey => write!(f, "ApiError::InvalidDictionaryItemKey")?,
749 ApiError::MissingSystemContractHash => write!(f, "ApiError::MissingContractHash")?,
750 ApiError::NonRepresentableSerialization => {
751 write!(f, "ApiError::NonRepresentableSerialization")?
752 }
753 ApiError::MessageTopicAlreadyRegistered => {
754 write!(f, "ApiError::MessageTopicAlreadyRegistered")?
755 }
756 ApiError::MaxTopicsNumberExceeded => write!(f, "ApiError::MaxTopicsNumberExceeded")?,
757 ApiError::MaxTopicNameSizeExceeded => write!(f, "ApiError::MaxTopicNameSizeExceeded")?,
758 ApiError::MessageTopicNotRegistered => {
759 write!(f, "ApiError::MessageTopicNotRegistered")?
760 }
761 ApiError::MessageTopicFull => write!(f, "ApiError::MessageTopicFull")?,
762 ApiError::MessageTooLarge => write!(f, "ApiError::MessageTooLarge")?,
763 ApiError::MaxMessagesPerBlockExceeded => {
764 write!(f, "ApiError::MaxMessagesPerBlockExceeded")?
765 }
766 ApiError::NotAllowedToAddContractVersion => {
767 write!(f, "ApiError::NotAllowedToAddContractVersion")?
768 }
769 ApiError::InvalidDelegationAmountLimits => {
770 write!(f, "ApiError::InvalidDelegationAmountLimits")?
771 }
772 ApiError::InvalidCallerInfoRequest => write!(f, "ApiError::InvalidCallerInfoRequest")?,
773 ApiError::ExceededRecursionDepth => write!(f, "ApiError::ExceededRecursionDepth")?,
774 ApiError::AuctionError(value) => write!(
775 f,
776 "ApiError::AuctionError({:?})",
777 auction::Error::try_from(*value).map_err(|_err| fmt::Error)?
778 )?,
779 ApiError::ContractHeader(value) => write!(
780 f,
781 "ApiError::ContractHeader({:?})",
782 addressable_entity::Error::try_from(*value).map_err(|_err| fmt::Error)?
783 )?,
784 ApiError::Mint(value) => write!(
785 f,
786 "ApiError::Mint({:?})",
787 mint::Error::try_from(*value).map_err(|_err| fmt::Error)?
788 )?,
789 ApiError::HandlePayment(value) => write!(
790 f,
791 "ApiError::HandlePayment({:?})",
792 handle_payment::Error::try_from(*value).map_err(|_err| fmt::Error)?
793 )?,
794 ApiError::User(value) => write!(f, "ApiError::User({})", value)?,
795 }
796 write!(f, " [{}]", u32::from(*self))
797 }
798}
799
800impl fmt::Display for ApiError {
801 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
802 match self {
803 ApiError::User(value) => write!(f, "User error: {}", value),
804 ApiError::ContractHeader(value) => write!(f, "Contract header error: {}", value),
805 ApiError::Mint(value) => write!(f, "Mint error: {}", value),
806 ApiError::HandlePayment(value) => write!(f, "Handle Payment error: {}", value),
807 _ => <Self as Debug>::fmt(self, f),
808 }
809 }
810}
811
812#[doc(hidden)]
814pub fn i32_from<T>(result: Result<(), T>) -> i32
815where
816 ApiError: From<T>,
817{
818 match result {
819 Ok(()) => 0,
820 Err(error) => {
821 let api_error = ApiError::from(error);
822 u32::from(api_error) as i32
823 }
824 }
825}
826
827pub fn result_from(value: i32) -> Result<(), ApiError> {
831 match value {
832 0 => Ok(()),
833 _ => Err(ApiError::from(value as u32)),
834 }
835}
836
837#[cfg(test)]
838mod tests {
839 use super::*;
840
841 fn round_trip(result: Result<(), ApiError>) {
842 let code = i32_from(result);
843 assert_eq!(result, result_from(code));
844 }
845
846 #[test]
847 fn error_values() {
848 assert_eq!(65_024_u32, u32::from(ApiError::Mint(0))); assert_eq!(65_279_u32, u32::from(ApiError::Mint(u8::MAX)));
850 assert_eq!(65_280_u32, u32::from(ApiError::HandlePayment(0))); assert_eq!(65_535_u32, u32::from(ApiError::HandlePayment(u8::MAX)));
852 assert_eq!(65_536_u32, u32::from(ApiError::User(0))); assert_eq!(131_071_u32, u32::from(ApiError::User(u16::MAX))); }
855
856 #[test]
857 fn error_descriptions_getkey() {
858 assert_eq!("ApiError::GetKey [8]", &format!("{:?}", ApiError::GetKey));
859 assert_eq!("ApiError::GetKey [8]", &format!("{}", ApiError::GetKey));
860 }
861
862 #[test]
863 fn error_descriptions_contract_header() {
864 assert_eq!(
865 "ApiError::ContractHeader(PreviouslyUsedVersion) [64769]",
866 &format!(
867 "{:?}",
868 ApiError::ContractHeader(addressable_entity::Error::PreviouslyUsedVersion as u8)
869 )
870 );
871 assert_eq!(
872 "Contract header error: 0",
873 &format!("{}", ApiError::ContractHeader(0))
874 );
875 assert_eq!(
876 "Contract header error: 255",
877 &format!("{}", ApiError::ContractHeader(u8::MAX))
878 );
879 }
880
881 #[test]
882 fn error_descriptions_mint() {
883 assert_eq!(
884 "ApiError::Mint(InsufficientFunds) [65024]",
885 &format!("{:?}", ApiError::Mint(0))
886 );
887 assert_eq!("Mint error: 0", &format!("{}", ApiError::Mint(0)));
888 assert_eq!("Mint error: 255", &format!("{}", ApiError::Mint(u8::MAX)));
889 }
890
891 #[test]
892 fn error_descriptions_handle_payment() {
893 assert_eq!(
894 "ApiError::HandlePayment(NotBonded) [65280]",
895 &format!(
896 "{:?}",
897 ApiError::HandlePayment(handle_payment::Error::NotBonded as u8)
898 )
899 );
900 }
901
902 #[test]
903 fn error_descriptions_handle_payment_display() {
904 assert_eq!(
905 "Handle Payment error: 0",
906 &format!(
907 "{}",
908 ApiError::HandlePayment(handle_payment::Error::NotBonded as u8)
909 )
910 );
911 }
912
913 #[test]
914 fn error_descriptions_user_errors() {
915 assert_eq!(
916 "ApiError::User(0) [65536]",
917 &format!("{:?}", ApiError::User(0))
918 );
919
920 assert_eq!("User error: 0", &format!("{}", ApiError::User(0)));
921 assert_eq!(
922 "ApiError::User(65535) [131071]",
923 &format!("{:?}", ApiError::User(u16::MAX))
924 );
925 assert_eq!(
926 "User error: 65535",
927 &format!("{}", ApiError::User(u16::MAX))
928 );
929 }
930
931 #[test]
932 fn error_edge_cases() {
933 assert_eq!(Err(ApiError::Unhandled), result_from(i32::MAX));
934 assert_eq!(
935 Err(ApiError::ContractHeader(255)),
936 result_from(MINT_ERROR_OFFSET as i32 - 1)
937 );
938 assert_eq!(Err(ApiError::Unhandled), result_from(-1));
939 assert_eq!(Err(ApiError::Unhandled), result_from(i32::MIN));
940 }
941
942 #[test]
943 fn error_round_trips() {
944 round_trip(Ok(()));
945 round_trip(Err(ApiError::None));
946 round_trip(Err(ApiError::MissingArgument));
947 round_trip(Err(ApiError::InvalidArgument));
948 round_trip(Err(ApiError::Deserialize));
949 round_trip(Err(ApiError::Read));
950 round_trip(Err(ApiError::ValueNotFound));
951 round_trip(Err(ApiError::ContractNotFound));
952 round_trip(Err(ApiError::GetKey));
953 round_trip(Err(ApiError::UnexpectedKeyVariant));
954 round_trip(Err(ApiError::UnexpectedContractRefVariant));
955 round_trip(Err(ApiError::InvalidPurseName));
956 round_trip(Err(ApiError::InvalidPurse));
957 round_trip(Err(ApiError::UpgradeContractAtURef));
958 round_trip(Err(ApiError::Transfer));
959 round_trip(Err(ApiError::NoAccessRights));
960 round_trip(Err(ApiError::CLTypeMismatch));
961 round_trip(Err(ApiError::EarlyEndOfStream));
962 round_trip(Err(ApiError::Formatting));
963 round_trip(Err(ApiError::LeftOverBytes));
964 round_trip(Err(ApiError::OutOfMemory));
965 round_trip(Err(ApiError::MaxKeysLimit));
966 round_trip(Err(ApiError::DuplicateKey));
967 round_trip(Err(ApiError::PermissionDenied));
968 round_trip(Err(ApiError::MissingKey));
969 round_trip(Err(ApiError::ThresholdViolation));
970 round_trip(Err(ApiError::KeyManagementThreshold));
971 round_trip(Err(ApiError::DeploymentThreshold));
972 round_trip(Err(ApiError::InsufficientTotalWeight));
973 round_trip(Err(ApiError::InvalidSystemContract));
974 round_trip(Err(ApiError::PurseNotCreated));
975 round_trip(Err(ApiError::Unhandled));
976 round_trip(Err(ApiError::BufferTooSmall));
977 round_trip(Err(ApiError::HostBufferEmpty));
978 round_trip(Err(ApiError::HostBufferFull));
979 round_trip(Err(ApiError::AllocLayout));
980 round_trip(Err(ApiError::NonRepresentableSerialization));
981 round_trip(Err(ApiError::ContractHeader(0)));
982 round_trip(Err(ApiError::ContractHeader(u8::MAX)));
983 round_trip(Err(ApiError::Mint(0)));
984 round_trip(Err(ApiError::Mint(u8::MAX)));
985 round_trip(Err(ApiError::HandlePayment(0)));
986 round_trip(Err(ApiError::HandlePayment(u8::MAX)));
987 round_trip(Err(ApiError::User(0)));
988 round_trip(Err(ApiError::User(u16::MAX)));
989 round_trip(Err(ApiError::AuctionError(0)));
990 round_trip(Err(ApiError::AuctionError(u8::MAX)));
991 round_trip(Err(ApiError::MessageTopicAlreadyRegistered));
992 round_trip(Err(ApiError::MaxTopicsNumberExceeded));
993 round_trip(Err(ApiError::MaxTopicNameSizeExceeded));
994 round_trip(Err(ApiError::MessageTopicNotRegistered));
995 round_trip(Err(ApiError::MessageTopicFull));
996 round_trip(Err(ApiError::MessageTooLarge));
997 round_trip(Err(ApiError::NotAllowedToAddContractVersion));
998 round_trip(Err(ApiError::InvalidDelegationAmountLimits));
999 }
1000}