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