1use crate::blueprints::access_controller::AccessControllerError;
2use crate::blueprints::account::AccountError;
3use crate::blueprints::consensus_manager::{ConsensusManagerError, ValidatorError};
4use crate::blueprints::package::PackageError;
5use crate::blueprints::pool::v1::errors::{
6 multi_resource_pool::Error as MultiResourcePoolError,
7 one_resource_pool::Error as OneResourcePoolError,
8 two_resource_pool::Error as TwoResourcePoolError,
9};
10use crate::blueprints::resource::{AuthZoneError, NonFungibleVaultError};
11use crate::blueprints::resource::{
12 BucketError, FungibleResourceManagerError, NonFungibleResourceManagerError, ProofError,
13 VaultError, WorktopError,
14};
15use crate::blueprints::transaction_processor::TransactionProcessorError;
16use crate::internal_prelude::*;
17use crate::kernel::call_frame::{
18 CallFrameDrainSubstatesError, CallFrameRemoveSubstateError, CallFrameScanKeysError,
19 CallFrameScanSortedSubstatesError, CallFrameSetSubstateError, CloseSubstateError,
20 CreateFrameError, CreateNodeError, DropNodeError, MarkTransientSubstateError,
21 MovePartitionError, OpenSubstateError, PassMessageError, PinNodeError, ReadSubstateError,
22 WriteSubstateError,
23};
24use crate::object_modules::metadata::MetadataError;
25use crate::object_modules::role_assignment::RoleAssignmentError;
26use crate::object_modules::royalty::ComponentRoyaltyError;
27use crate::system::system_modules::auth::AuthError;
28use crate::system::system_modules::costing::CostingError;
29use crate::system::system_modules::limits::TransactionLimitsError;
30use crate::system::system_type_checker::TypeCheckError;
31use crate::transaction::AbortReason;
32use crate::vm::wasm::WasmRuntimeError;
33use crate::vm::ScryptoVmVersionError;
34use radix_engine_interface::api::object_api::ModuleId;
35use radix_engine_interface::api::{ActorStateHandle, AttachedModuleId};
36use radix_engine_interface::blueprints::package::{BlueprintPartitionType, CanonicalBlueprintId};
37use radix_transactions::model::IntentHash;
38use sbor::representations::PrintMode;
39
40#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
41pub enum IdAllocationError {
42 OutOfID,
43}
44
45pub trait CanBeAbortion {
46 fn abortion(&self) -> Option<&AbortReason>;
47}
48
49pub mod error_models {
50 use radix_common::prelude::*;
51
52 #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, ScryptoSbor)]
55 #[sbor(
56 as_type = "Reference",
57 as_ref = "&Reference(self.0)",
58 from_value = "Self(value.0)",
59 type_name = "NodeId"
60 )]
61 pub struct ReferencedNodeId(pub radix_common::prelude::NodeId);
62
63 impl Debug for ReferencedNodeId {
64 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
65 self.0.fmt(f)
66 }
67 }
68
69 impl From<radix_common::prelude::NodeId> for ReferencedNodeId {
70 fn from(value: radix_common::prelude::NodeId) -> Self {
71 Self(value)
72 }
73 }
74
75 #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, ScryptoSbor)]
78 #[sbor(
79 as_type = "Own",
80 as_ref = "&Own(self.0)",
81 from_value = "Self(value.0)",
82 type_name = "NodeId"
83 )]
84 pub struct OwnedNodeId(pub radix_common::prelude::NodeId);
85
86 impl Debug for OwnedNodeId {
87 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
88 self.0.fmt(f)
89 }
90 }
91
92 impl From<radix_common::prelude::NodeId> for OwnedNodeId {
93 fn from(value: radix_common::prelude::NodeId) -> Self {
94 Self(value)
95 }
96 }
97}
98
99lazy_static::lazy_static! {
100 static ref HISTORIC_REJECTION_REASON_SCHEMAS: [ScryptoSingleTypeSchema; 1] = {
104 [
105 ScryptoSingleTypeSchema::from(include_bytes!("rejection_reason_cuttlefish_schema.bin")),
106 ]
107 };
108}
109
110#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
112pub enum RejectionReason {
116 TransactionEpochNotYetValid {
117 valid_from: Epoch,
119 current_epoch: Epoch,
120 },
121 TransactionEpochNoLongerValid {
122 valid_until: Epoch,
124 current_epoch: Epoch,
125 },
126 TransactionProposerTimestampNotYetValid {
127 valid_from_inclusive: Instant,
128 current_time: Instant,
129 },
130 TransactionProposerTimestampNoLongerValid {
131 valid_to_exclusive: Instant,
132 current_time: Instant,
133 },
134 IntentHashPreviouslyCommitted(IntentHash),
135 IntentHashPreviouslyCancelled(IntentHash),
136
137 BootloadingError(BootloadingError),
138
139 ErrorBeforeLoanAndDeferredCostsRepaid(RuntimeError),
140 SuccessButFeeLoanNotRepaid,
141 SubintentsNotYetSupported,
142}
143
144impl<'a> ContextualDisplay<ScryptoValueDisplayContext<'a>> for RejectionReason {
145 type Error = fmt::Error;
146
147 fn contextual_format<F: fmt::Write>(
148 &self,
149 f: &mut F,
150 context: &ScryptoValueDisplayContext,
151 ) -> Result<(), Self::Error> {
152 self.create_persistable().contextual_format(f, context)
153 }
154}
155
156impl RejectionReason {
157 pub fn create_persistable(&self) -> PersistableRejectionReason {
158 PersistableRejectionReason {
159 schema_index: HISTORIC_REJECTION_REASON_SCHEMAS.len() as u32 - 1,
160 encoded_rejection_reason: scrypto_decode(&scrypto_encode(self).unwrap()).unwrap(),
161 }
162 }
163}
164
165#[derive(Debug, Clone, ScryptoSbor)]
166pub struct PersistableRejectionReason {
167 pub schema_index: u32,
168 pub encoded_rejection_reason: ScryptoOwnedRawValue,
169}
170
171impl<'a> ContextualDisplay<ScryptoValueDisplayContext<'a>> for PersistableRejectionReason {
172 type Error = fmt::Error;
173
174 fn contextual_format<F: fmt::Write>(
176 &self,
177 f: &mut F,
178 context: &ScryptoValueDisplayContext,
179 ) -> Result<(), Self::Error> {
180 let value = &self.encoded_rejection_reason;
181 let formatted_optional = HISTORIC_REJECTION_REASON_SCHEMAS
182 .get(self.schema_index as usize)
183 .and_then(|schema| {
184 format_debug_like_value(
185 f,
186 schema,
187 value,
188 sbor::representations::PrintMode::SingleLine,
189 *context,
190 )
191 });
192 match formatted_optional {
193 Some(result) => result,
194 None => match scrypto_encode(&value) {
195 Ok(encoded) => write!(f, "UnknownRejectionReason({})", hex::encode(encoded)),
196 Err(error) => write!(f, "CannotDisplayRejectionReason({error:?})"),
197 },
198 }
199 }
200}
201
202fn format_debug_like_value(
203 f: &mut impl fmt::Write,
204 schema: &SingleTypeSchema<ScryptoCustomSchema>,
205 value: &ScryptoRawValue,
206 print_mode: PrintMode,
207 custom_context: ScryptoValueDisplayContext,
208) -> Option<fmt::Result> {
209 use sbor::representations::*;
210 let type_id = schema.type_id;
211 let schema = schema.schema.as_unique_version();
212 let depth_limit = SCRYPTO_SBOR_V1_MAX_DEPTH;
213
214 validate_partial_payload_against_schema::<ScryptoCustomExtension, _>(
216 value.value_body_bytes(),
217 traversal::ExpectedStart::ValueBody(value.value_kind()),
218 true,
219 0,
220 schema,
221 type_id,
222 &(),
223 depth_limit,
224 )
225 .ok()?;
226
227 let display_parameters = ValueDisplayParameters::Annotated {
229 display_mode: DisplayMode::RustLike(RustLikeOptions::debug_like()),
230 print_mode,
231 custom_context,
232 schema,
233 type_id,
234 depth_limit,
235 };
236
237 Some(write!(f, "{}", value.display(display_parameters)))
238}
239
240impl From<BootloadingError> for RejectionReason {
241 fn from(value: BootloadingError) -> Self {
242 RejectionReason::BootloadingError(value)
243 }
244}
245
246#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
247pub enum TransactionExecutionError {
248 BootloadingError(BootloadingError),
250
251 RuntimeError(RuntimeError),
253}
254
255#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
256pub enum BootloadingError {
257 ReferencedNodeDoesNotExist(error_models::ReferencedNodeId),
258 ReferencedNodeIsNotAnObject(error_models::ReferencedNodeId),
259 ReferencedNodeDoesNotAllowDirectAccess(error_models::ReferencedNodeId),
260
261 FailedToApplyDeferredCosts(CostingError),
262}
263
264lazy_static::lazy_static! {
265 static ref HISTORIC_RUNTIME_ERROR_SCHEMAS: [ScryptoSingleTypeSchema; 2] = {
287 [
288 ScryptoSingleTypeSchema::from(include_bytes!("runtime_error_pre_cuttlefish_schema.bin")),
289 ScryptoSingleTypeSchema::from(include_bytes!("runtime_error_cuttlefish_schema.bin")),
290 ]
291 };
292}
293
294#[derive(Clone, PartialEq, Eq, ScryptoSbor, Debug)]
296pub enum RuntimeError {
316 KernelError(KernelError),
318
319 SystemError(SystemError),
321
322 SystemModuleError(SystemModuleError),
325
326 SystemUpstreamError(SystemUpstreamError),
329
330 VmError(VmError),
332
333 ApplicationError(ApplicationError),
335
336 FinalizationCostingError(CostingError),
337}
338
339impl<'a> ContextualDisplay<ScryptoValueDisplayContext<'a>> for RuntimeError {
340 type Error = fmt::Error;
341
342 fn contextual_format<F: fmt::Write>(
343 &self,
344 f: &mut F,
345 context: &ScryptoValueDisplayContext,
346 ) -> Result<(), Self::Error> {
347 self.create_persistable().contextual_format(f, context)
348 }
349}
350
351impl RuntimeError {
352 pub fn create_persistable(&self) -> PersistableRuntimeError {
353 PersistableRuntimeError {
354 schema_index: HISTORIC_RUNTIME_ERROR_SCHEMAS.len() as u32 - 1,
355 encoded_error: scrypto_decode(&scrypto_encode(self).unwrap()).unwrap(),
356 }
357 }
358}
359
360#[derive(Debug, Clone, ScryptoSbor)]
361pub struct PersistableRuntimeError {
362 pub schema_index: u32,
363 pub encoded_error: ScryptoOwnedRawValue,
367}
368
369impl<'a> ContextualDisplay<ScryptoValueDisplayContext<'a>> for PersistableRuntimeError {
384 type Error = fmt::Error;
385
386 fn contextual_format<F: fmt::Write>(
387 &self,
388 f: &mut F,
389 context: &ScryptoValueDisplayContext,
390 ) -> Result<(), Self::Error> {
391 let value = &self.encoded_error;
392 let formatted_optional = HISTORIC_RUNTIME_ERROR_SCHEMAS
393 .get(self.schema_index as usize)
394 .and_then(|schema| {
395 format_debug_like_value(f, schema, value, PrintMode::SingleLine, *context)
396 });
397 match formatted_optional {
398 Some(result) => result,
399 None => match scrypto_encode(&value) {
400 Ok(encoded) => write!(f, "UnknownError({})", hex::encode(encoded)),
401 Err(error) => write!(f, "CannotDisplayError({error:?})"),
402 },
403 }
404 }
405}
406
407impl SystemApiError for RuntimeError {}
408
409impl From<KernelError> for RuntimeError {
410 fn from(error: KernelError) -> Self {
411 RuntimeError::KernelError(error.into())
412 }
413}
414
415impl From<SystemUpstreamError> for RuntimeError {
416 fn from(error: SystemUpstreamError) -> Self {
417 RuntimeError::SystemUpstreamError(error.into())
418 }
419}
420
421impl From<SystemModuleError> for RuntimeError {
422 fn from(error: SystemModuleError) -> Self {
423 RuntimeError::SystemModuleError(error.into())
424 }
425}
426
427impl From<ApplicationError> for RuntimeError {
428 fn from(error: ApplicationError) -> Self {
429 RuntimeError::ApplicationError(error.into())
430 }
431}
432
433impl CanBeAbortion for RuntimeError {
434 fn abortion(&self) -> Option<&AbortReason> {
435 match self {
436 RuntimeError::KernelError(_) => None,
437 RuntimeError::VmError(_) => None,
438 RuntimeError::SystemError(_) => None,
439 RuntimeError::SystemUpstreamError(_) => None,
440 RuntimeError::SystemModuleError(err) => err.abortion(),
441 RuntimeError::ApplicationError(_) => None,
442 RuntimeError::FinalizationCostingError(_) => None,
443 }
444 }
445}
446
447#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
448pub enum KernelError {
449 CallFrameError(CallFrameError),
451
452 IdAllocationError(IdAllocationError),
454
455 SubstateHandleDoesNotExist(SubstateHandle),
457
458 OrphanedNodes(Vec<error_models::OwnedNodeId>),
459
460 StackError(StackError),
461}
462
463#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
464pub struct InvalidDropAccess {
465 pub node_id: error_models::ReferencedNodeId,
466 pub package_address: PackageAddress,
467 pub blueprint_name: String,
468 pub actor_package: Option<PackageAddress>,
469}
470
471#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
472pub struct InvalidGlobalizeAccess {
473 pub package_address: PackageAddress,
474 pub blueprint_name: String,
475 pub actor_package: Option<PackageAddress>,
476}
477
478impl CanBeAbortion for VmError {
479 fn abortion(&self) -> Option<&AbortReason> {
480 match self {
481 VmError::Wasm(err) => err.abortion(),
482 _ => None,
483 }
484 }
485}
486
487impl From<CallFrameError> for KernelError {
488 fn from(value: CallFrameError) -> Self {
489 KernelError::CallFrameError(value)
490 }
491}
492
493#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
494pub enum CallFrameError {
495 CreateFrameError(CreateFrameError),
496 PassMessageError(PassMessageError),
497
498 CreateNodeError(CreateNodeError),
499 DropNodeError(DropNodeError),
500 PinNodeError(PinNodeError),
501
502 MovePartitionError(MovePartitionError),
503
504 MarkTransientSubstateError(MarkTransientSubstateError),
505 OpenSubstateError(OpenSubstateError),
506 CloseSubstateError(CloseSubstateError),
507 ReadSubstateError(ReadSubstateError),
508 WriteSubstateError(WriteSubstateError),
509
510 ScanSubstatesError(CallFrameScanKeysError),
511 DrainSubstatesError(CallFrameDrainSubstatesError),
512 ScanSortedSubstatesError(CallFrameScanSortedSubstatesError),
513 SetSubstatesError(CallFrameSetSubstateError),
514 RemoveSubstatesError(CallFrameRemoveSubstateError),
515}
516
517#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
518pub enum StackError {
519 InvalidStackId,
520}
521
522#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
523pub enum SystemError {
524 NoBlueprintId,
525 NoPackageAddress,
526 InvalidActorStateHandle,
527 InvalidActorRefHandle,
528
529 GlobalizingTransientBlueprint,
530 GlobalAddressDoesNotExist,
531 NotAnAddressReservation,
532 NotAnObject,
533 NotAKeyValueStore,
534 ModulesDontHaveOuterObjects,
535 ActorNodeIdDoesNotExist,
536 OuterObjectDoesNotExist,
537 NotAFieldHandle,
538 NotAFieldWriteHandle,
539 RootHasNoType,
540 AddressBech32EncodeError,
541 TypeCheckError(TypeCheckError),
542 FieldDoesNotExist(BlueprintId, u8),
543 CollectionIndexDoesNotExist(BlueprintId, u8),
544 CollectionIndexIsOfWrongType(
545 BlueprintId,
546 u8,
547 BlueprintPartitionType,
548 BlueprintPartitionType,
549 ),
550 KeyValueEntryLocked,
551 FieldLocked(ActorStateHandle, u8),
552 ObjectModuleDoesNotExist(AttachedModuleId),
553 NotAKeyValueEntryHandle,
554 NotAKeyValueEntryWriteHandle,
555 InvalidLockFlags,
556 CannotGlobalize(CannotGlobalizeError),
557 MissingModule(ModuleId),
558 InvalidGlobalAddressReservation,
559 InvalidChildObjectCreation,
560 InvalidModuleType(Box<InvalidModuleType>),
561 CreateObjectError(Box<CreateObjectError>),
562 InvalidGenericArgs,
563 InvalidFeature(String),
564 AssertAccessRuleFailed,
565 BlueprintDoesNotExist(CanonicalBlueprintId),
566 AuthTemplateDoesNotExist(CanonicalBlueprintId),
567 InvalidGlobalizeAccess(Box<InvalidGlobalizeAccess>),
568 InvalidDropAccess(Box<InvalidDropAccess>),
569 CostingModuleNotEnabled,
570 AuthModuleNotEnabled,
571 TransactionRuntimeModuleNotEnabled,
572 ForceWriteEventFlagsNotAllowed,
573
574 BlueprintTypeNotFound(String),
575
576 BlsError(String),
577 InputDataEmpty,
578
579 SystemPanic(String),
584
585 CannotLockFeeInChildSubintent(usize),
586 IntentError(IntentError),
587}
588
589#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
590pub enum IntentError {
591 CannotVerifyParentOnRoot,
592 CannotYieldProof,
593 VerifyParentFailed,
594 InvalidIntentIndex(usize),
595 NoParentToYieldTo,
596 AssertNextCallReturnsFailed(ResourceConstraintsError),
597 AssertBucketContentsFailed(ResourceConstraintError),
598}
599
600#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
601pub enum EventError {
602 SchemaNotFoundError {
603 blueprint: BlueprintId,
604 event_name: String,
605 },
606 EventSchemaNotMatch(String),
607 NoAssociatedPackage,
608 InvalidActor,
609}
610
611#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
612pub enum SystemUpstreamError {
613 SystemFunctionCallNotAllowed,
614
615 FnNotFound(String),
616 ReceiverNotMatch(String),
617 HookNotFound(BlueprintHook),
618
619 InputDecodeError(DecodeError),
620 InputSchemaNotMatch(String, String),
621
622 OutputDecodeError(DecodeError),
623 OutputSchemaNotMatch(String, String),
624}
625
626#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
627pub enum VmError {
628 Native(NativeRuntimeError),
629 Wasm(WasmRuntimeError),
630 ScryptoVmVersion(ScryptoVmVersionError),
631}
632
633#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
634pub enum NativeRuntimeError {
635 InvalidCodeId,
636
637 Trap {
639 export_name: String,
640 input: ScryptoValue,
641 error: String,
642 },
643}
644
645#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
646pub enum CreateObjectError {
647 BlueprintNotFound(String),
648 InvalidFieldDueToFeature(BlueprintId, u8),
649 MissingField(BlueprintId, u8),
650 InvalidFieldIndex(BlueprintId, u8),
651 SchemaValidationError(BlueprintId, String),
652 InvalidSubstateWrite(String),
653}
654
655#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
656pub enum SystemModuleError {
657 AuthError(AuthError),
658 CostingError(CostingError),
659 TransactionLimitsError(TransactionLimitsError),
660 EventError(Box<EventError>),
661}
662
663#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
664pub struct InvalidModuleType {
665 pub expected_blueprint: BlueprintId,
666 pub actual_blueprint: BlueprintId,
667}
668
669#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
670pub enum CannotGlobalizeError {
671 NotAnObject,
672 AlreadyGlobalized,
673 InvalidBlueprintId,
674}
675
676impl CanBeAbortion for SystemModuleError {
677 fn abortion(&self) -> Option<&AbortReason> {
678 match self {
679 Self::CostingError(err) => err.abortion(),
680 _ => None,
681 }
682 }
683}
684
685impl From<AuthError> for SystemModuleError {
686 fn from(error: AuthError) -> Self {
687 Self::AuthError(error)
688 }
689}
690
691impl From<CostingError> for SystemModuleError {
692 fn from(error: CostingError) -> Self {
693 Self::CostingError(error)
694 }
695}
696
697#[derive(Debug, Clone)]
701pub enum InvokeError<E: SelfError> {
702 SelfError(E),
703 Downstream(RuntimeError),
704}
705
706pub trait SelfError {
709 fn into_runtime_error(self) -> RuntimeError;
710}
711
712impl<E: Into<ApplicationError>> SelfError for E {
713 fn into_runtime_error(self) -> RuntimeError {
714 self.into().into()
715 }
716}
717
718impl<E: SelfError> From<RuntimeError> for InvokeError<E> {
719 fn from(runtime_error: RuntimeError) -> Self {
720 InvokeError::Downstream(runtime_error)
721 }
722}
723
724impl<E: SelfError> From<E> for InvokeError<E> {
725 fn from(error: E) -> Self {
726 InvokeError::SelfError(error)
727 }
728}
729
730impl<E: SelfError> InvokeError<E> {
731 pub fn error(error: E) -> Self {
732 InvokeError::SelfError(error)
733 }
734
735 pub fn downstream(runtime_error: RuntimeError) -> Self {
736 InvokeError::Downstream(runtime_error)
737 }
738}
739
740impl<E: SelfError> From<InvokeError<E>> for RuntimeError {
741 fn from(error: InvokeError<E>) -> Self {
742 match error {
743 InvokeError::Downstream(runtime_error) => runtime_error,
744 InvokeError::SelfError(e) => e.into_runtime_error(),
745 }
746 }
747}
748
749#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
750pub enum ApplicationError {
751 ExportDoesNotExist(String),
756
757 InputDecodeError(DecodeError),
759
760 PanicMessage(String),
762
763 RoleAssignmentError(RoleAssignmentError),
767
768 MetadataError(MetadataError),
769
770 ComponentRoyaltyError(ComponentRoyaltyError),
771
772 TransactionProcessorError(TransactionProcessorError),
776
777 PackageError(PackageError),
778
779 ConsensusManagerError(ConsensusManagerError),
780
781 ValidatorError(ValidatorError),
782
783 FungibleResourceManagerError(FungibleResourceManagerError),
784
785 NonFungibleResourceManagerError(NonFungibleResourceManagerError),
786
787 BucketError(BucketError),
788
789 ProofError(ProofError),
790
791 NonFungibleVaultError(NonFungibleVaultError),
792
793 VaultError(VaultError),
794
795 WorktopError(WorktopError),
796
797 AuthZoneError(AuthZoneError),
798
799 AccountError(AccountError),
800
801 AccessControllerError(AccessControllerError),
802
803 OneResourcePoolError(OneResourcePoolError),
804
805 TwoResourcePoolError(TwoResourcePoolError),
806
807 MultiResourcePoolError(MultiResourcePoolError),
808}
809
810impl From<TransactionProcessorError> for ApplicationError {
811 fn from(value: TransactionProcessorError) -> Self {
812 Self::TransactionProcessorError(value)
813 }
814}
815
816impl From<PackageError> for ApplicationError {
817 fn from(value: PackageError) -> Self {
818 Self::PackageError(value)
819 }
820}
821
822impl From<ConsensusManagerError> for ApplicationError {
823 fn from(value: ConsensusManagerError) -> Self {
824 Self::ConsensusManagerError(value)
825 }
826}
827
828impl From<FungibleResourceManagerError> for ApplicationError {
829 fn from(value: FungibleResourceManagerError) -> Self {
830 Self::FungibleResourceManagerError(value)
831 }
832}
833
834impl From<RoleAssignmentError> for ApplicationError {
835 fn from(value: RoleAssignmentError) -> Self {
836 Self::RoleAssignmentError(value)
837 }
838}
839
840impl From<BucketError> for ApplicationError {
841 fn from(value: BucketError) -> Self {
842 Self::BucketError(value)
843 }
844}
845
846impl From<ProofError> for ApplicationError {
847 fn from(value: ProofError) -> Self {
848 Self::ProofError(value)
849 }
850}
851
852impl From<VaultError> for ApplicationError {
853 fn from(value: VaultError) -> Self {
854 Self::VaultError(value)
855 }
856}
857
858impl From<WorktopError> for ApplicationError {
859 fn from(value: WorktopError) -> Self {
860 Self::WorktopError(value)
861 }
862}
863
864impl From<AuthZoneError> for ApplicationError {
865 fn from(value: AuthZoneError) -> Self {
866 Self::AuthZoneError(value)
867 }
868}
869
870impl From<OpenSubstateError> for CallFrameError {
871 fn from(value: OpenSubstateError) -> Self {
872 Self::OpenSubstateError(value)
873 }
874}
875
876impl From<CloseSubstateError> for CallFrameError {
877 fn from(value: CloseSubstateError) -> Self {
878 Self::CloseSubstateError(value)
879 }
880}
881
882impl From<PassMessageError> for CallFrameError {
883 fn from(value: PassMessageError) -> Self {
884 Self::PassMessageError(value)
885 }
886}
887
888impl From<MovePartitionError> for CallFrameError {
889 fn from(value: MovePartitionError) -> Self {
890 Self::MovePartitionError(value)
891 }
892}
893
894impl From<ReadSubstateError> for CallFrameError {
895 fn from(value: ReadSubstateError) -> Self {
896 Self::ReadSubstateError(value)
897 }
898}
899
900impl From<WriteSubstateError> for CallFrameError {
901 fn from(value: WriteSubstateError) -> Self {
902 Self::WriteSubstateError(value)
903 }
904}
905
906impl From<CreateNodeError> for CallFrameError {
907 fn from(value: CreateNodeError) -> Self {
908 Self::CreateNodeError(value)
909 }
910}
911
912impl From<DropNodeError> for CallFrameError {
913 fn from(value: DropNodeError) -> Self {
914 Self::DropNodeError(value)
915 }
916}
917
918impl From<CreateFrameError> for CallFrameError {
919 fn from(value: CreateFrameError) -> Self {
920 Self::CreateFrameError(value)
921 }
922}
923
924impl From<CallFrameScanKeysError> for CallFrameError {
925 fn from(value: CallFrameScanKeysError) -> Self {
926 Self::ScanSubstatesError(value)
927 }
928}
929
930impl From<CallFrameScanSortedSubstatesError> for CallFrameError {
931 fn from(value: CallFrameScanSortedSubstatesError) -> Self {
932 Self::ScanSortedSubstatesError(value)
933 }
934}
935
936impl From<CallFrameDrainSubstatesError> for CallFrameError {
937 fn from(value: CallFrameDrainSubstatesError) -> Self {
938 Self::DrainSubstatesError(value)
939 }
940}
941
942impl From<CallFrameSetSubstateError> for CallFrameError {
943 fn from(value: CallFrameSetSubstateError) -> Self {
944 Self::SetSubstatesError(value)
945 }
946}
947
948impl From<CallFrameRemoveSubstateError> for CallFrameError {
949 fn from(value: CallFrameRemoveSubstateError) -> Self {
950 Self::RemoveSubstatesError(value)
951 }
952}
953
954impl<T> From<T> for RuntimeError
955where
956 T: Into<CallFrameError>,
957{
958 fn from(value: T) -> Self {
959 Self::KernelError(KernelError::CallFrameError(value.into()))
960 }
961}
962
963#[cfg(test)]
964mod tests {
965 use super::*;
966
967 #[test]
968 fn the_current_runtime_error_schema_is_last_on_historic_list() {
969 let latest = HISTORIC_RUNTIME_ERROR_SCHEMAS.last().unwrap();
970 let current = generate_single_type_schema::<RuntimeError, ScryptoCustomSchema>();
971
972 compare_single_type_schemas(
974 &SchemaComparisonSettings::require_equality(),
975 latest,
976 ¤t,
977 )
978 .assert_valid("latest", "current");
979 }
980
981 #[test]
982 fn the_current_runtime_error_schema_has_no_raw_node_ids() {
983 let current = generate_single_type_schema::<RuntimeError, ScryptoCustomSchema>();
984 assert_no_raw_node_ids(¤t);
985 }
986
987 #[test]
988 fn the_current_rejection_reason_schema_is_last_on_historic_list() {
989 let latest = HISTORIC_REJECTION_REASON_SCHEMAS.last().unwrap();
990 let current = generate_single_type_schema::<RejectionReason, ScryptoCustomSchema>();
991
992 compare_single_type_schemas(
994 &SchemaComparisonSettings::require_equality(),
995 latest,
996 ¤t,
997 )
998 .assert_valid("latest", "current");
999 }
1000
1001 #[test]
1002 fn the_current_rejection_reason_schema_has_no_raw_node_ids() {
1003 let current = generate_single_type_schema::<RejectionReason, ScryptoCustomSchema>();
1004 assert_no_raw_node_ids(¤t);
1005 }
1006
1007 fn assert_no_raw_node_ids(schema: &SingleTypeSchema<ScryptoCustomSchema>) {
1008 let schema = schema.schema.as_unique_version();
1009 for (type_kind, type_metadata) in schema.type_kinds.iter().zip(schema.type_metadata.iter())
1010 {
1011 if type_metadata.type_name.as_deref() == Some("NodeId") {
1012 match type_kind {
1013 TypeKind::Custom(ScryptoCustomTypeKind::Own)
1014 | TypeKind::Custom(ScryptoCustomTypeKind::Reference) => {}
1015 _ => {
1016 let mut formatted_schema = String::new();
1017 format_debug_like_value(
1018 &mut formatted_schema,
1019 &generate_single_type_schema::<
1020 SchemaV1<ScryptoCustomSchema>,
1021 ScryptoCustomSchema,
1022 >(),
1023 &scrypto_decode(&scrypto_encode(schema).unwrap()).unwrap(),
1024 PrintMode::MultiLine {
1025 indent_size: 4,
1026 base_indent: 4,
1027 first_line_indent: 4,
1028 },
1029 ScryptoValueDisplayContext::default(),
1030 );
1031 panic!("A raw NodeId was detected somewhere in the error schema. Use `error_models::ReferencedNodeId` or `error_models::OwnedNodeId` instead.\n\nSchema:\n{}", formatted_schema);
1036 }
1037 }
1038 }
1039 }
1040 }
1041
1042 #[test]
1043 fn runtime_error_string() {
1044 let network = NetworkDefinition::mainnet();
1045 let address_encoder = AddressBech32Encoder::new(&network);
1046 let address_encoder = Some(&address_encoder);
1047
1048 {
1050 let runtime_error = RuntimeError::ApplicationError(ApplicationError::AccountError(
1051 AccountError::VaultDoesNotExist {
1052 resource_address: XRD,
1053 },
1054 ));
1055
1056 let debugged = format!("{:?}", runtime_error);
1058 assert_eq!(debugged, "ApplicationError(AccountError(VaultDoesNotExist { resource_address: ResourceAddress(5da66318c6318c61f5a61b4c6318c6318cf794aa8d295f14e6318c6318c6) }))");
1059
1060 let rendered = runtime_error.to_string(address_encoder);
1062 assert_eq!(rendered, "ApplicationError(AccountError(VaultDoesNotExist { resource_address: ResourceAddress(\"resource_rdx1tknxxxxxxxxxradxrdxxxxxxxxx009923554798xxxxxxxxxradxrd\") }))");
1063 }
1064
1065 {
1067 let mut id_allocator = crate::kernel::id_allocator::IdAllocator::new(hash("seed-data"));
1068
1069 let bucket_entity_type = EntityType::InternalGenericComponent;
1071 let example_bucket_1 = id_allocator.allocate_node_id(bucket_entity_type).unwrap();
1072 let example_bucket_2 = id_allocator.allocate_node_id(bucket_entity_type).unwrap();
1073 let runtime_error = RuntimeError::KernelError(KernelError::OrphanedNodes(vec![
1074 example_bucket_1.into(),
1075 example_bucket_2.into(),
1076 ]));
1077
1078 let debugged = format!("{:?}", runtime_error);
1080 assert_eq!(debugged, "KernelError(OrphanedNodes([NodeId(\"f82ee60dbc11caa1594fccdbb8031c41af8084344bcbe7a4c784491a7d4c\"), NodeId(\"f8abce267317b7bdd859951840ccd25f1ea7e83c538d507e0f82da7b9aed\")]))");
1081
1082 let rendered = runtime_error.to_string(address_encoder);
1084 assert_eq!(rendered, "KernelError(OrphanedNodes([NodeId(\"internal_component_rdx1lqhwvrduz892zk20endmsqcugxhcppp5f0970fx8s3y35l2vv5mzfn\"), NodeId(\"internal_component_rdx1lz4uufnnz7mmmkzej5vypnxjtu0206pu2wx4qls0std8hxhd3v84yv\")]))");
1085 }
1086 }
1087}