tx3_resolver/trp/
errors.rs1use serde_json::json;
2use tx3_tir::encoding;
3
4use crate::{
5 inputs::{CanonicalQuery, SearchSpace},
6 trp::spec,
7 Error,
8};
9
10pub const CODE_UNSUPPORTED_TIR: i32 = -32000;
11pub const CODE_MISSING_TX_ARG: i32 = -32001;
12pub const CODE_INPUT_NOT_RESOLVED: i32 = -32002;
13pub const CODE_TX_SCRIPT_FAILURE: i32 = -32003;
14pub const CODE_TX_NOT_ACCEPTED: i32 = -32004;
15pub const CODE_INTEROP_ERROR: i32 = -32005;
16pub const CODE_COMPILE_ERROR: i32 = -32006;
17pub const CODE_INPUT_QUERY_TOO_BROAD: i32 = -32007;
18pub const CODE_UTXO_STORE_ERROR: i32 = -32008;
19pub const CODE_TRANSIENT_ERROR: i32 = -32009;
20
21pub trait TrpError {
27 fn code(&self) -> i32;
28 fn data(&self) -> Option<serde_json::Value>;
29}
30
31pub trait IntoErrorData {
32 type Output;
33 fn into_error_data(self) -> Self::Output;
34}
35
36impl IntoErrorData for CanonicalQuery {
37 type Output = spec::InputQueryDiagnostic;
38
39 fn into_error_data(self) -> Self::Output {
40 spec::InputQueryDiagnostic {
41 address: self.address.as_ref().map(hex::encode),
42 min_amount: self
43 .min_amount
44 .iter()
45 .flat_map(|x| x.iter())
46 .map(|(k, v)| (k.to_string(), v.to_string()))
47 .collect(),
48 refs: self
49 .refs
50 .iter()
51 .map(ToString::to_string)
52 .collect::<Vec<_>>(),
53 support_many: self.support_many,
54 collateral: self.collateral,
55 }
56 }
57}
58
59impl IntoErrorData for SearchSpace {
60 type Output = spec::SearchSpaceDiagnostic;
61
62 fn into_error_data(self) -> Self::Output {
63 spec::SearchSpaceDiagnostic {
64 matched: self
65 .take(Some(10))
66 .iter()
67 .map(ToString::to_string)
68 .collect::<Vec<_>>(),
69 by_address_count: self.by_address_count,
70 by_asset_class_count: self.by_asset_class_count,
71 by_ref_count: self.by_ref_count,
72 }
73 }
74}
75
76impl TrpError for encoding::Error {
77 fn code(&self) -> i32 {
78 match self {
79 encoding::Error::DeprecatedTirVersion(_) => CODE_UNSUPPORTED_TIR,
80 encoding::Error::UnknownTirVersion(_) => CODE_UNSUPPORTED_TIR,
81 encoding::Error::TirDeserializeError(_) => CODE_UNSUPPORTED_TIR,
82 }
83 }
84
85 fn data(&self) -> Option<serde_json::Value> {
86 match self {
87 encoding::Error::DeprecatedTirVersion(version) => {
88 let data = spec::UnsupportedTirDiagnostic {
89 provided: version.to_string(),
90 expected: tx3_tir::encoding::MIN_SUPPORTED_VERSION.to_string(),
91 };
92
93 Some(json!(data))
94 }
95 encoding::Error::UnknownTirVersion(version) => {
96 let data = spec::UnsupportedTirDiagnostic {
97 provided: version.to_string(),
98 expected: tx3_tir::encoding::MIN_SUPPORTED_VERSION.to_string(),
99 };
100
101 Some(json!(data))
102 }
103 encoding::Error::TirDeserializeError(_) => None,
104 }
105 }
106}
107
108impl TrpError for crate::Error {
109 fn code(&self) -> i32 {
110 match self {
111 Error::InputQueryTooBroad => CODE_INPUT_QUERY_TOO_BROAD,
112 Error::InputNotResolved(..) => CODE_INPUT_NOT_RESOLVED,
113 Error::MissingTxArg { .. } => CODE_MISSING_TX_ARG,
114 Error::CompileError(..) => CODE_COMPILE_ERROR,
115 Error::CantCompileNonConstantTir => CODE_COMPILE_ERROR,
116 Error::ExpectedData(..) => CODE_COMPILE_ERROR,
117 Error::TransientError(_) => CODE_TRANSIENT_ERROR,
118 Error::StoreError(_) => CODE_UTXO_STORE_ERROR,
119 Error::InteropError(_) => CODE_INTEROP_ERROR,
120 Error::ReduceError(_) => CODE_COMPILE_ERROR,
121 Error::TxScriptFailure(_) => CODE_TX_SCRIPT_FAILURE,
122 Error::TxNotAccepted(_) => CODE_TX_NOT_ACCEPTED,
123 Error::TirEncodingError(x) => x.code(),
124 }
125 }
126
127 fn data(&self) -> Option<serde_json::Value> {
128 match self {
129 Error::TirEncodingError(x) => x.data(),
130
131 Error::MissingTxArg { key, ty } => {
132 let data = spec::MissingTxArgDiagnostic {
133 key: key.to_string(),
134 ty: format!("{ty:?}"),
135 };
136
137 Some(json!(data))
138 }
139 Error::InputNotResolved(name, q, ss) => {
140 let data = spec::InputNotResolvedDiagnostic {
141 name: name.to_string(),
142 query: q.clone().into_error_data(),
143 search_space: ss.clone().into_error_data(),
144 };
145
146 Some(json!(data))
147 }
148
149 Error::TxScriptFailure(x) => {
150 let data = spec::TxScriptFailureDiagnostic { logs: x.clone() };
151 Some(json!(data))
152 }
153 _ => None,
154 }
155 }
156}