sui_transaction_builder/
error.rs1use sui_sdk_types::Address;
5
6#[derive(thiserror::Error, Debug, Clone)]
8#[non_exhaustive]
9pub enum Error {
10 #[error("Conversion error due to input issue: {0}")]
11 Input(String),
12 #[error("Gas object should be an immutable or owned object")]
13 WrongGasObject,
14 #[error("Missing object id")]
15 MissingObjectId,
16 #[error("Missing version for object {0}")]
17 MissingVersion(Address),
18 #[error("Missing digest for object {0}")]
19 MissingDigest(Address),
20 #[error("Missing sender")]
21 MissingSender,
22 #[error("Missing gas objects")]
23 MissingGasObjects,
24 #[error("Missing gas budget")]
25 MissingGasBudget,
26 #[error("Missing gas price")]
27 MissingGasPrice,
28 #[error("Missing object kind for object {0}")]
29 MissingObjectKind(Address),
30 #[error("Unknown shared object mutability for object {0}")]
31 SharedObjectMutability(Address),
32 #[error("{0}")]
33 #[cfg(feature = "intents")]
34 #[cfg_attr(doc_cfg, doc(cfg(feature = "intents")))]
35 SimulationFailure(Box<SimulationFailure>),
36}
37
38#[derive(Debug, Clone)]
40#[cfg(feature = "intents")]
41#[cfg_attr(doc_cfg, doc(cfg(feature = "intents")))]
42pub struct SimulationFailure {
43 error: sui_rpc::proto::sui::rpc::v2::ExecutionError,
45}
46
47#[cfg(feature = "intents")]
48impl SimulationFailure {
49 pub(crate) fn new(error: sui_rpc::proto::sui::rpc::v2::ExecutionError) -> Self {
50 Self { error }
51 }
52
53 pub fn execution_error(&self) -> &sui_rpc::proto::sui::rpc::v2::ExecutionError {
55 &self.error
56 }
57
58 pub fn description(&self) -> Option<&str> {
60 self.error.description_opt()
61 }
62
63 pub fn command(&self) -> Option<u64> {
65 self.error.command_opt()
66 }
67
68 pub fn kind(
70 &self,
71 ) -> Option<sui_rpc::proto::sui::rpc::v2::execution_error::ExecutionErrorKind> {
72 self.error.kind.and_then(|k| {
73 sui_rpc::proto::sui::rpc::v2::execution_error::ExecutionErrorKind::try_from(k).ok()
74 })
75 }
76
77 pub fn move_abort(&self) -> Option<&sui_rpc::proto::sui::rpc::v2::MoveAbort> {
79 self.error.abort_opt()
80 }
81
82 pub fn clever_error(&self) -> Option<&sui_rpc::proto::sui::rpc::v2::CleverError> {
87 self.error.abort_opt()?.clever_error.as_ref()
88 }
89}
90
91#[cfg(feature = "intents")]
92impl std::fmt::Display for SimulationFailure {
93 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94 write!(f, "transaction simulation failed")?;
95
96 if let Some(cmd) = self.command() {
97 write!(f, " in command {cmd}")?;
98 }
99
100 if let Some(kind) = self.kind() {
101 write!(f, " ({})", kind.as_str_name())?;
102 }
103
104 if let Some(desc) = self.description()
105 && !desc.is_empty()
106 {
107 write!(f, ": {desc}")?;
108 }
109
110 if let Some(abort) = self.move_abort() {
111 if let Some(loc) = &abort.location
112 && let (Some(pkg), Some(module)) = (loc.package.as_deref(), loc.module.as_deref())
113 {
114 write!(f, " at {pkg}::{module}")?;
115 if let Some(func) = loc.function_name.as_deref() {
116 write!(f, "::{func}")?;
117 }
118 }
119
120 if let Some(clever) = &abort.clever_error
121 && let Some(name) = clever.constant_name.as_deref()
122 {
123 write!(f, " [{name}")?;
124 if let Some(sui_rpc::proto::sui::rpc::v2::clever_error::Value::Rendered(v)) =
125 &clever.value
126 {
127 write!(f, " = {v}")?;
128 }
129 write!(f, "]")?;
130 }
131 }
132
133 Ok(())
134 }
135}