sc_rpc_spec_v2/transaction/
error.rs1use crate::transaction::event::{TransactionError, TransactionEvent};
24use jsonrpsee::types::error::ErrorObject;
25use sc_transaction_pool_api::error::Error as PoolError;
26use sp_runtime::transaction_validity::InvalidTransaction;
27
28#[derive(Debug, thiserror::Error)]
30pub enum Error {
31	#[error("Transaction pool error: {}", .0)]
33	Pool(#[from] PoolError),
34	#[error("Extrinsic verification error: {}", .0)]
36	Verification(Box<dyn std::error::Error + Send + Sync>),
37}
38
39impl<Hash> From<Error> for TransactionEvent<Hash> {
40	fn from(e: Error) -> Self {
41		match e {
42			Error::Verification(e) => TransactionEvent::Invalid(TransactionError {
43				error: format!("Verification error: {}", e),
44			}),
45			Error::Pool(PoolError::InvalidTransaction(InvalidTransaction::Custom(e))) =>
46				TransactionEvent::Invalid(TransactionError {
47					error: format!("Invalid transaction with custom error: {}", e),
48				}),
49			Error::Pool(PoolError::InvalidTransaction(e)) => {
50				let msg: &str = e.into();
51				TransactionEvent::Invalid(TransactionError {
52					error: format!("Invalid transaction: {}", msg),
53				})
54			},
55			Error::Pool(PoolError::UnknownTransaction(e)) => {
56				let msg: &str = e.into();
57				TransactionEvent::Invalid(TransactionError {
58					error: format!("Unknown transaction validity: {}", msg),
59				})
60			},
61			Error::Pool(PoolError::TemporarilyBanned) =>
62				TransactionEvent::Invalid(TransactionError {
63					error: "Transaction is temporarily banned".into(),
64				}),
65			Error::Pool(PoolError::AlreadyImported(_)) =>
66				TransactionEvent::Invalid(TransactionError {
67					error: "Transaction is already imported".into(),
68				}),
69			Error::Pool(PoolError::TooLowPriority { old, new }) =>
70				TransactionEvent::Invalid(TransactionError {
71					error: format!(
72						"The priority of the transaction is too low (pool {} > current {})",
73						old, new
74					),
75				}),
76			Error::Pool(PoolError::CycleDetected) => TransactionEvent::Invalid(TransactionError {
77				error: "The transaction contains a cyclic dependency".into(),
78			}),
79			Error::Pool(PoolError::ImmediatelyDropped) =>
80				TransactionEvent::Invalid(TransactionError {
81					error: "The transaction could not enter the pool because of the limit".into(),
82				}),
83			Error::Pool(PoolError::Unactionable) => TransactionEvent::Invalid(TransactionError {
84				error: "Transaction cannot be propagated and the local node does not author blocks"
85					.into(),
86			}),
87			Error::Pool(PoolError::NoTagsProvided) => TransactionEvent::Invalid(TransactionError {
88				error: "Transaction does not provide any tags, so the pool cannot identify it"
89					.into(),
90			}),
91			Error::Pool(PoolError::InvalidBlockId(_)) =>
92				TransactionEvent::Invalid(TransactionError {
93					error: "The provided block ID is not valid".into(),
94				}),
95			Error::Pool(PoolError::RejectedFutureTransaction) =>
96				TransactionEvent::Invalid(TransactionError {
97					error: "The pool is not accepting future transactions".into(),
98				}),
99		}
100	}
101}
102
103#[derive(Debug, thiserror::Error)]
105pub enum ErrorBroadcast {
106	#[error("Invalid operation id")]
108	InvalidOperationID,
109}
110
111pub mod json_rpc_spec {
114	pub const INVALID_PARAM_ERROR: i32 = -32602;
116}
117
118impl From<ErrorBroadcast> for ErrorObject<'static> {
119	fn from(e: ErrorBroadcast) -> Self {
120		let msg = e.to_string();
121
122		match e {
123			ErrorBroadcast::InvalidOperationID =>
124				ErrorObject::owned(json_rpc_spec::INVALID_PARAM_ERROR, msg, None::<()>),
125		}
126	}
127}