lightning_signer/policy/
error.rs1#[cfg(feature = "use_backtrace")]
2use backtrace::Backtrace;
3
4use ValidationErrorKind::*;
5
6use crate::prelude::*;
7
8#[derive(Clone, Debug, PartialEq)]
10pub enum ValidationErrorKind {
11 TransactionFormat(String),
13 ScriptFormat(String),
15 Mismatch(String),
17 Policy(String),
19 TemporaryPolicy(String),
23 UnknownDestinations(String, Vec<usize>),
26}
27
28impl PartialEq for ValidationError {
30 fn eq(&self, other: &ValidationError) -> bool {
31 self.kind == other.kind
32 }
33}
34
35#[derive(Clone)]
37pub struct ValidationError {
38 pub kind: ValidationErrorKind,
40 #[cfg(feature = "use_backtrace")]
42 pub bt: Backtrace,
43}
44
45impl ValidationError {
46 #[cfg(feature = "use_backtrace")]
48 pub fn resolved_backtrace(&self) -> Backtrace {
49 let mut mve = self.clone();
50 mve.bt.resolve();
51 mve.bt
52 }
53
54 pub fn prepend_msg(&self, premsg: String) -> ValidationError {
56 let modkind = match &self.kind {
57 TransactionFormat(s0) => TransactionFormat(premsg + &s0),
58 ScriptFormat(s0) => ScriptFormat(premsg + &s0),
59 Mismatch(s0) => Mismatch(premsg + &s0),
60 Policy(s0) => Policy(premsg + &s0),
61 TemporaryPolicy(s0) => TemporaryPolicy(premsg + &s0),
62 UnknownDestinations(s0, indices) => UnknownDestinations(premsg + &s0, indices.clone()),
63 };
64 ValidationError {
65 kind: modkind,
66 #[cfg(feature = "use_backtrace")]
67 bt: self.bt.clone(),
68 }
69 }
70}
71
72impl core::fmt::Display for ValidationError {
73 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
74 write!(f, "{:?}", self.kind)
75 }
76}
77
78impl core::fmt::Debug for ValidationError {
79 #[cfg(not(feature = "use_backtrace"))]
80 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
81 f.debug_struct("ValidationError").field("kind", &self.kind).finish()
82 }
83 #[cfg(feature = "use_backtrace")]
84 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
85 f.debug_struct("ValidationError")
86 .field("kind", &self.kind)
87 .field("bt", &self.resolved_backtrace())
88 .finish()
89 }
90}
91
92impl Into<String> for ValidationError {
93 fn into(self) -> String {
94 match self.kind {
95 TransactionFormat(s) => "transaction format: ".to_string() + &s,
96 ScriptFormat(s) => "script format: ".to_string() + &s,
97 Mismatch(s) => "script template mismatch: ".to_string() + &s,
98 Policy(s) => "policy failure: ".to_string() + &s,
99 TemporaryPolicy(s) => "temporary policy failure: ".to_string() + &s,
100 UnknownDestinations(s, indices) => {
101 format!("unknown destinations: {} {:?}", s, indices)
102 }
103 }
104 }
105}
106
107pub(crate) fn transaction_format_error(msg: impl Into<String>) -> ValidationError {
108 ValidationError {
109 kind: TransactionFormat(msg.into()),
110 #[cfg(feature = "use_backtrace")]
111 bt: Backtrace::new_unresolved(),
112 }
113}
114
115pub(crate) fn script_format_error(msg: impl Into<String>) -> ValidationError {
116 ValidationError {
117 kind: ScriptFormat(msg.into()),
118 #[cfg(feature = "use_backtrace")]
119 bt: Backtrace::new_unresolved(),
120 }
121}
122
123pub(crate) fn mismatch_error(msg: impl Into<String>) -> ValidationError {
124 ValidationError {
125 kind: Mismatch(msg.into()),
126 #[cfg(feature = "use_backtrace")]
127 bt: Backtrace::new_unresolved(),
128 }
129}
130
131pub(crate) fn policy_error(msg: impl Into<String>) -> ValidationError {
132 ValidationError {
133 kind: Policy(msg.into()),
134 #[cfg(feature = "use_backtrace")]
135 bt: Backtrace::new_unresolved(),
136 }
137}
138
139pub(crate) fn temporary_policy_error(msg: impl Into<String>) -> ValidationError {
140 ValidationError {
141 kind: TemporaryPolicy(msg.into()),
142 #[cfg(feature = "use_backtrace")]
143 bt: Backtrace::new_unresolved(),
144 }
145}
146
147pub(crate) fn unknown_destinations_error(unknowns: Vec<usize>) -> ValidationError {
148 ValidationError {
149 kind: UnknownDestinations("".to_string(), unknowns),
150 #[cfg(feature = "use_backtrace")]
151 bt: Backtrace::new_unresolved(),
152 }
153}
154
155#[allow(unused)]
157macro_rules! transaction_format_err {
158 ($obj:expr, $tag:tt, $($arg:tt)*) => (
159 return Err(transaction_format_error(format!(
160 "{}: {}",
161 short_function!(),
162 format!($($arg)*)
163 )))
164 )
165}
166
167#[doc(hidden)]
170#[macro_export]
171#[allow(unused)]
172macro_rules! policy_err {
173 ($obj:expr, $tag:tt, $($arg:tt)*) => (
174 $obj.policy().policy_error($tag.into(), format!(
175 "{}: {}",
176 short_function!(),
177 format!($($arg)*)
178 ))?
179 )
180}
181
182#[doc(hidden)]
185#[macro_export]
186#[allow(unused)]
187macro_rules! temporary_policy_err {
188 ($obj:expr, $tag:tt, $($arg:tt)*) => (
189 $obj.policy().temporary_policy_error($tag.into(), format!(
190 "{}: {}",
191 short_function!(),
192 format!($($arg)*)
193 ))?
194 )
195}
196
197#[allow(unused)]
198#[macro_export]
199macro_rules! policy_log {
201 ($obj:expr, $tag:tt, $($arg:tt)*) => (
202 $obj.policy().policy_log($tag.into(), format!(
203 "{}: {}",
204 short_function!(),
205 format!($($arg)*)
206 ))
207 )
208}
209
210#[cfg(test)]
211mod tests {
212 use super::*;
213
214 #[test]
215 fn validation_error_test() {
216 assert_eq!(
217 format!("{}", transaction_format_error("testing".to_string())),
218 "TransactionFormat(\"testing\")"
219 );
220 assert_eq!(
221 Into::<String>::into(transaction_format_error("testing".to_string())),
222 "transaction format: testing"
223 );
224 assert_eq!(
225 format!("{}", script_format_error("testing".to_string())),
226 "ScriptFormat(\"testing\")"
227 );
228 assert_eq!(
229 Into::<String>::into(script_format_error("testing".to_string())),
230 "script format: testing"
231 );
232 assert_eq!(format!("{}", mismatch_error("testing".to_string())), "Mismatch(\"testing\")");
233 assert_eq!(
234 Into::<String>::into(mismatch_error("testing".to_string())),
235 "script template mismatch: testing"
236 );
237 assert_eq!(format!("{}", policy_error("testing".to_string())), "Policy(\"testing\")");
238 assert_eq!(
239 Into::<String>::into(policy_error("testing".to_string())),
240 "policy failure: testing"
241 );
242 }
243}