flow_lib/
errors.rs

1#![allow(non_snake_case)]
2
3use std::convert::Infallible;
4use std::io;
5
6use actix::MailboxError;
7use anyhow::anyhow;
8use futures::channel::oneshot::Canceled;
9use serde::{Deserialize, Serialize};
10use serde_with::{serde_as, serde_conv};
11use solana_message::CompileError;
12use solana_program::clock::Slot;
13use solana_pubkey::Pubkey;
14use solana_rpc_client_api::client_error::{Error as ClientError, ErrorKind as ClientErrorKind};
15use solana_rpc_client_api::request::{RpcError, RpcRequest, RpcResponseErrorData};
16use solana_rpc_client_api::response::RpcSimulateTransactionResult;
17use solana_sanitize::SanitizeError;
18use solana_signer::{PresignerError, SignerError};
19use solana_transaction_error::TransactionError;
20
21#[derive(Serialize, Deserialize)]
22pub enum AsRpcRequestImpl {
23    Custom,
24    DeregisterNode,
25    GetAccountInfo,
26    GetBalance,
27    GetBlock,
28    GetBlockHeight,
29    GetBlockProduction,
30    GetBlocks,
31    GetBlocksWithLimit,
32    GetBlockTime,
33    GetClusterNodes,
34    GetEpochInfo,
35    GetEpochSchedule,
36    GetFeeForMessage,
37    GetFirstAvailableBlock,
38    GetGenesisHash,
39    GetHealth,
40    GetIdentity,
41    GetInflationGovernor,
42    GetInflationRate,
43    GetInflationReward,
44    GetLargestAccounts,
45    GetLatestBlockhash,
46    GetLeaderSchedule,
47    GetMaxRetransmitSlot,
48    GetMaxShredInsertSlot,
49    GetMinimumBalanceForRentExemption,
50    GetMultipleAccounts,
51    GetProgramAccounts,
52    GetRecentPerformanceSamples,
53    GetRecentPrioritizationFees,
54    GetHighestSnapshotSlot,
55    GetSignaturesForAddress,
56    GetSignatureStatuses,
57    GetSlot,
58    GetSlotLeader,
59    GetSlotLeaders,
60    GetStorageTurn,
61    GetStorageTurnRate,
62    GetSlotsPerSegment,
63    GetStakeMinimumDelegation,
64    GetStoragePubkeysForSlot,
65    GetSupply,
66    GetTokenAccountBalance,
67    GetTokenAccountsByDelegate,
68    GetTokenAccountsByOwner,
69    GetTokenLargestAccounts,
70    GetTokenSupply,
71    GetTransaction,
72    GetTransactionCount,
73    GetVersion,
74    GetVoteAccounts,
75    IsBlockhashValid,
76    MinimumLedgerSlot,
77    RegisterNode,
78    RequestAirdrop,
79    SendTransaction,
80    SimulateTransaction,
81    SignVote,
82}
83
84fn ser_rpc_request(r: &RpcRequest) -> AsRpcRequestImpl {
85    match r {
86        RpcRequest::Custom { .. } => AsRpcRequestImpl::Custom,
87        RpcRequest::DeregisterNode => AsRpcRequestImpl::DeregisterNode,
88        RpcRequest::GetAccountInfo => AsRpcRequestImpl::GetAccountInfo,
89        RpcRequest::GetBalance => AsRpcRequestImpl::GetBalance,
90        RpcRequest::GetBlock => AsRpcRequestImpl::GetBlock,
91        RpcRequest::GetBlockHeight => AsRpcRequestImpl::GetBlockHeight,
92        RpcRequest::GetBlockProduction => AsRpcRequestImpl::GetBlockProduction,
93        RpcRequest::GetBlocks => AsRpcRequestImpl::GetBlocks,
94        RpcRequest::GetBlocksWithLimit => AsRpcRequestImpl::GetBlocksWithLimit,
95        RpcRequest::GetBlockTime => AsRpcRequestImpl::GetBlockTime,
96        RpcRequest::GetClusterNodes => AsRpcRequestImpl::GetClusterNodes,
97        RpcRequest::GetEpochInfo => AsRpcRequestImpl::GetEpochInfo,
98        RpcRequest::GetEpochSchedule => AsRpcRequestImpl::GetEpochSchedule,
99        RpcRequest::GetFeeForMessage => AsRpcRequestImpl::GetFeeForMessage,
100        RpcRequest::GetFirstAvailableBlock => AsRpcRequestImpl::GetFirstAvailableBlock,
101        RpcRequest::GetGenesisHash => AsRpcRequestImpl::GetGenesisHash,
102        RpcRequest::GetHealth => AsRpcRequestImpl::GetHealth,
103        RpcRequest::GetIdentity => AsRpcRequestImpl::GetIdentity,
104        RpcRequest::GetInflationGovernor => AsRpcRequestImpl::GetInflationGovernor,
105        RpcRequest::GetInflationRate => AsRpcRequestImpl::GetInflationRate,
106        RpcRequest::GetInflationReward => AsRpcRequestImpl::GetInflationReward,
107        RpcRequest::GetLargestAccounts => AsRpcRequestImpl::GetLargestAccounts,
108        RpcRequest::GetLatestBlockhash => AsRpcRequestImpl::GetLatestBlockhash,
109        RpcRequest::GetLeaderSchedule => AsRpcRequestImpl::GetLeaderSchedule,
110        RpcRequest::GetMaxRetransmitSlot => AsRpcRequestImpl::GetMaxRetransmitSlot,
111        RpcRequest::GetMaxShredInsertSlot => AsRpcRequestImpl::GetMaxShredInsertSlot,
112        RpcRequest::GetMinimumBalanceForRentExemption => {
113            AsRpcRequestImpl::GetMinimumBalanceForRentExemption
114        }
115        RpcRequest::GetMultipleAccounts => AsRpcRequestImpl::GetMultipleAccounts,
116        RpcRequest::GetProgramAccounts => AsRpcRequestImpl::GetProgramAccounts,
117        RpcRequest::GetRecentPerformanceSamples => AsRpcRequestImpl::GetRecentPerformanceSamples,
118        RpcRequest::GetRecentPrioritizationFees => AsRpcRequestImpl::GetRecentPrioritizationFees,
119        RpcRequest::GetHighestSnapshotSlot => AsRpcRequestImpl::GetHighestSnapshotSlot,
120        RpcRequest::GetSignaturesForAddress => AsRpcRequestImpl::GetSignaturesForAddress,
121        RpcRequest::GetSignatureStatuses => AsRpcRequestImpl::GetSignatureStatuses,
122        RpcRequest::GetSlot => AsRpcRequestImpl::GetSlot,
123        RpcRequest::GetSlotLeader => AsRpcRequestImpl::GetSlotLeader,
124        RpcRequest::GetSlotLeaders => AsRpcRequestImpl::GetSlotLeaders,
125        RpcRequest::GetStorageTurn => AsRpcRequestImpl::GetStorageTurn,
126        RpcRequest::GetStorageTurnRate => AsRpcRequestImpl::GetStorageTurnRate,
127        RpcRequest::GetSlotsPerSegment => AsRpcRequestImpl::GetSlotsPerSegment,
128        RpcRequest::GetStakeMinimumDelegation => AsRpcRequestImpl::GetStakeMinimumDelegation,
129        RpcRequest::GetStoragePubkeysForSlot => AsRpcRequestImpl::GetStoragePubkeysForSlot,
130        RpcRequest::GetSupply => AsRpcRequestImpl::GetSupply,
131        RpcRequest::GetTokenAccountBalance => AsRpcRequestImpl::GetTokenAccountBalance,
132        RpcRequest::GetTokenAccountsByDelegate => AsRpcRequestImpl::GetTokenAccountsByDelegate,
133        RpcRequest::GetTokenAccountsByOwner => AsRpcRequestImpl::GetTokenAccountsByOwner,
134        RpcRequest::GetTokenLargestAccounts => AsRpcRequestImpl::GetTokenLargestAccounts,
135        RpcRequest::GetTokenSupply => AsRpcRequestImpl::GetTokenSupply,
136        RpcRequest::GetTransaction => AsRpcRequestImpl::GetTransaction,
137        RpcRequest::GetTransactionCount => AsRpcRequestImpl::GetTransactionCount,
138        RpcRequest::GetVersion => AsRpcRequestImpl::GetVersion,
139        RpcRequest::GetVoteAccounts => AsRpcRequestImpl::GetVoteAccounts,
140        RpcRequest::IsBlockhashValid => AsRpcRequestImpl::IsBlockhashValid,
141        RpcRequest::MinimumLedgerSlot => AsRpcRequestImpl::MinimumLedgerSlot,
142        RpcRequest::RegisterNode => AsRpcRequestImpl::RegisterNode,
143        RpcRequest::RequestAirdrop => AsRpcRequestImpl::RequestAirdrop,
144        RpcRequest::SendTransaction => AsRpcRequestImpl::SendTransaction,
145        RpcRequest::SimulateTransaction => AsRpcRequestImpl::SimulateTransaction,
146        RpcRequest::SignVote => AsRpcRequestImpl::SignVote,
147    }
148}
149
150fn de_rpc_request(r: AsRpcRequestImpl) -> Result<RpcRequest, Infallible> {
151    Ok(match r {
152        AsRpcRequestImpl::Custom => RpcRequest::Custom { method: "unknown" },
153        AsRpcRequestImpl::DeregisterNode => RpcRequest::DeregisterNode,
154        AsRpcRequestImpl::GetAccountInfo => RpcRequest::GetAccountInfo,
155        AsRpcRequestImpl::GetBalance => RpcRequest::GetBalance,
156        AsRpcRequestImpl::GetBlock => RpcRequest::GetBlock,
157        AsRpcRequestImpl::GetBlockHeight => RpcRequest::GetBlockHeight,
158        AsRpcRequestImpl::GetBlockProduction => RpcRequest::GetBlockProduction,
159        AsRpcRequestImpl::GetBlocks => RpcRequest::GetBlocks,
160        AsRpcRequestImpl::GetBlocksWithLimit => RpcRequest::GetBlocksWithLimit,
161        AsRpcRequestImpl::GetBlockTime => RpcRequest::GetBlockTime,
162        AsRpcRequestImpl::GetClusterNodes => RpcRequest::GetClusterNodes,
163        AsRpcRequestImpl::GetEpochInfo => RpcRequest::GetEpochInfo,
164        AsRpcRequestImpl::GetEpochSchedule => RpcRequest::GetEpochSchedule,
165        AsRpcRequestImpl::GetFeeForMessage => RpcRequest::GetFeeForMessage,
166        AsRpcRequestImpl::GetFirstAvailableBlock => RpcRequest::GetFirstAvailableBlock,
167        AsRpcRequestImpl::GetGenesisHash => RpcRequest::GetGenesisHash,
168        AsRpcRequestImpl::GetHealth => RpcRequest::GetHealth,
169        AsRpcRequestImpl::GetIdentity => RpcRequest::GetIdentity,
170        AsRpcRequestImpl::GetInflationGovernor => RpcRequest::GetInflationGovernor,
171        AsRpcRequestImpl::GetInflationRate => RpcRequest::GetInflationRate,
172        AsRpcRequestImpl::GetInflationReward => RpcRequest::GetInflationReward,
173        AsRpcRequestImpl::GetLargestAccounts => RpcRequest::GetLargestAccounts,
174        AsRpcRequestImpl::GetLatestBlockhash => RpcRequest::GetLatestBlockhash,
175        AsRpcRequestImpl::GetLeaderSchedule => RpcRequest::GetLeaderSchedule,
176        AsRpcRequestImpl::GetMaxRetransmitSlot => RpcRequest::GetMaxRetransmitSlot,
177        AsRpcRequestImpl::GetMaxShredInsertSlot => RpcRequest::GetMaxShredInsertSlot,
178        AsRpcRequestImpl::GetMinimumBalanceForRentExemption => {
179            RpcRequest::GetMinimumBalanceForRentExemption
180        }
181        AsRpcRequestImpl::GetMultipleAccounts => RpcRequest::GetMultipleAccounts,
182        AsRpcRequestImpl::GetProgramAccounts => RpcRequest::GetProgramAccounts,
183        AsRpcRequestImpl::GetRecentPerformanceSamples => RpcRequest::GetRecentPerformanceSamples,
184        AsRpcRequestImpl::GetRecentPrioritizationFees => RpcRequest::GetRecentPrioritizationFees,
185        AsRpcRequestImpl::GetHighestSnapshotSlot => RpcRequest::GetHighestSnapshotSlot,
186        AsRpcRequestImpl::GetSignaturesForAddress => RpcRequest::GetSignaturesForAddress,
187        AsRpcRequestImpl::GetSignatureStatuses => RpcRequest::GetSignatureStatuses,
188        AsRpcRequestImpl::GetSlot => RpcRequest::GetSlot,
189        AsRpcRequestImpl::GetSlotLeader => RpcRequest::GetSlotLeader,
190        AsRpcRequestImpl::GetSlotLeaders => RpcRequest::GetSlotLeaders,
191        AsRpcRequestImpl::GetStorageTurn => RpcRequest::GetStorageTurn,
192        AsRpcRequestImpl::GetStorageTurnRate => RpcRequest::GetStorageTurnRate,
193        AsRpcRequestImpl::GetSlotsPerSegment => RpcRequest::GetSlotsPerSegment,
194        AsRpcRequestImpl::GetStakeMinimumDelegation => RpcRequest::GetStakeMinimumDelegation,
195        AsRpcRequestImpl::GetStoragePubkeysForSlot => RpcRequest::GetStoragePubkeysForSlot,
196        AsRpcRequestImpl::GetSupply => RpcRequest::GetSupply,
197        AsRpcRequestImpl::GetTokenAccountBalance => RpcRequest::GetTokenAccountBalance,
198        AsRpcRequestImpl::GetTokenAccountsByDelegate => RpcRequest::GetTokenAccountsByDelegate,
199        AsRpcRequestImpl::GetTokenAccountsByOwner => RpcRequest::GetTokenAccountsByOwner,
200        AsRpcRequestImpl::GetTokenLargestAccounts => RpcRequest::GetTokenLargestAccounts,
201        AsRpcRequestImpl::GetTokenSupply => RpcRequest::GetTokenSupply,
202        AsRpcRequestImpl::GetTransaction => RpcRequest::GetTransaction,
203        AsRpcRequestImpl::GetTransactionCount => RpcRequest::GetTransactionCount,
204        AsRpcRequestImpl::GetVersion => RpcRequest::GetVersion,
205        AsRpcRequestImpl::GetVoteAccounts => RpcRequest::GetVoteAccounts,
206        AsRpcRequestImpl::IsBlockhashValid => RpcRequest::IsBlockhashValid,
207        AsRpcRequestImpl::MinimumLedgerSlot => RpcRequest::MinimumLedgerSlot,
208        AsRpcRequestImpl::RegisterNode => RpcRequest::RegisterNode,
209        AsRpcRequestImpl::RequestAirdrop => RpcRequest::RequestAirdrop,
210        AsRpcRequestImpl::SendTransaction => RpcRequest::SendTransaction,
211        AsRpcRequestImpl::SimulateTransaction => RpcRequest::SimulateTransaction,
212        AsRpcRequestImpl::SignVote => RpcRequest::SignVote,
213    })
214}
215
216serde_conv!(pub AsRpcRequest, RpcRequest, ser_rpc_request, de_rpc_request);
217
218#[derive(Serialize, Deserialize)]
219pub enum AsRpcResponseErrorDataImpl {
220    Empty,
221    SendTransactionPreflightFailure(RpcSimulateTransactionResult),
222    NodeUnhealthy { num_slots_behind: Option<Slot> },
223}
224
225fn ser_rpc_response_error_data(error: &RpcResponseErrorData) -> AsRpcResponseErrorDataImpl {
226    match error {
227        RpcResponseErrorData::Empty => AsRpcResponseErrorDataImpl::Empty,
228        RpcResponseErrorData::SendTransactionPreflightFailure(rpc_simulate_transaction_result) => {
229            AsRpcResponseErrorDataImpl::SendTransactionPreflightFailure(
230                rpc_simulate_transaction_result.clone(),
231            )
232        }
233        RpcResponseErrorData::NodeUnhealthy { num_slots_behind } => {
234            AsRpcResponseErrorDataImpl::NodeUnhealthy {
235                num_slots_behind: *num_slots_behind,
236            }
237        }
238    }
239}
240
241fn de_rpc_response_error_data(
242    error: AsRpcResponseErrorDataImpl,
243) -> Result<RpcResponseErrorData, Infallible> {
244    Ok(match error {
245        AsRpcResponseErrorDataImpl::Empty => RpcResponseErrorData::Empty,
246        AsRpcResponseErrorDataImpl::SendTransactionPreflightFailure(
247            rpc_simulate_transaction_result,
248        ) => RpcResponseErrorData::SendTransactionPreflightFailure(rpc_simulate_transaction_result),
249        AsRpcResponseErrorDataImpl::NodeUnhealthy { num_slots_behind } => {
250            RpcResponseErrorData::NodeUnhealthy { num_slots_behind }
251        }
252    })
253}
254
255serde_conv!(pub AsRpcResponseErrorData, RpcResponseErrorData, ser_rpc_response_error_data, de_rpc_response_error_data);
256
257#[serde_as]
258#[derive(Serialize, Deserialize)]
259pub enum AsRpcErrorImpl {
260    RpcRequestError(String),
261    RpcResponseError {
262        code: i64,
263        message: String,
264        #[serde_as(as = "AsRpcResponseErrorData")]
265        data: RpcResponseErrorData,
266    },
267    ParseError(String),
268    ForUser(String),
269}
270
271fn ser_rpc_error(error: &RpcError) -> AsRpcErrorImpl {
272    match error {
273        RpcError::RpcRequestError(error) => AsRpcErrorImpl::RpcRequestError(error.clone()),
274        RpcError::RpcResponseError {
275            code,
276            message,
277            data,
278        } => AsRpcErrorImpl::RpcResponseError {
279            code: *code,
280            message: message.clone(),
281            data: clone_rpc_response_error(data),
282        },
283        RpcError::ParseError(error) => AsRpcErrorImpl::ParseError(error.clone()),
284        RpcError::ForUser(error) => AsRpcErrorImpl::ForUser(error.clone()),
285    }
286}
287
288fn de_rpc_error(error: AsRpcErrorImpl) -> Result<RpcError, Infallible> {
289    Ok(match error {
290        AsRpcErrorImpl::RpcRequestError(error) => RpcError::RpcRequestError(error),
291        AsRpcErrorImpl::RpcResponseError {
292            code,
293            message,
294            data,
295        } => RpcError::RpcResponseError {
296            code,
297            message,
298            data,
299        },
300        AsRpcErrorImpl::ParseError(error) => RpcError::ParseError(error),
301        AsRpcErrorImpl::ForUser(error) => RpcError::ForUser(error),
302    })
303}
304
305serde_conv!(pub AsRpcEeror, RpcError, ser_rpc_error, de_rpc_error);
306
307#[serde_as]
308#[derive(Serialize, Deserialize)]
309pub enum AsClientErrorKindImpl {
310    Io(#[serde_as(as = "AsIoError")] io::Error),
311    Middleware(#[serde_as(as = "AsAnyhow")] anyhow::Error),
312    RpcError(#[serde_as(as = "AsRpcEeror")] RpcError),
313    SigningError(#[serde_as(as = "AsSignerError")] SignerError),
314    TransactionError(TransactionError),
315    Custom(String),
316}
317
318#[derive(Serialize, Deserialize)]
319pub enum AsErrorKindImpl {
320    NotFound,
321    PermissionDenied,
322    ConnectionRefused,
323    ConnectionReset,
324    HostUnreachable,
325    NetworkUnreachable,
326    ConnectionAborted,
327    NotConnected,
328    AddrInUse,
329    AddrNotAvailable,
330    NetworkDown,
331    BrokenPipe,
332    AlreadyExists,
333    WouldBlock,
334    NotADirectory,
335    IsADirectory,
336    DirectoryNotEmpty,
337    ReadOnlyFilesystem,
338    StaleNetworkFileHandle,
339    InvalidInput,
340    InvalidData,
341    TimedOut,
342    WriteZero,
343    StorageFull,
344    NotSeekable,
345    QuotaExceeded,
346    FileTooLarge,
347    ResourceBusy,
348    ExecutableFileBusy,
349    Deadlock,
350    CrossesDevices,
351    TooManyLinks,
352    InvalidFilename,
353    ArgumentListTooLong,
354    Interrupted,
355    Unsupported,
356    UnexpectedEof,
357    OutOfMemory,
358    Other,
359}
360
361fn ser_error_kind(kind: &io::ErrorKind) -> AsErrorKindImpl {
362    match kind {
363        io::ErrorKind::NotFound => AsErrorKindImpl::NotFound,
364        io::ErrorKind::PermissionDenied => AsErrorKindImpl::PermissionDenied,
365        io::ErrorKind::ConnectionRefused => AsErrorKindImpl::ConnectionRefused,
366        io::ErrorKind::ConnectionReset => AsErrorKindImpl::ConnectionReset,
367        io::ErrorKind::HostUnreachable => AsErrorKindImpl::HostUnreachable,
368        io::ErrorKind::NetworkUnreachable => AsErrorKindImpl::NetworkUnreachable,
369        io::ErrorKind::ConnectionAborted => AsErrorKindImpl::ConnectionAborted,
370        io::ErrorKind::NotConnected => AsErrorKindImpl::NotConnected,
371        io::ErrorKind::AddrInUse => AsErrorKindImpl::AddrInUse,
372        io::ErrorKind::AddrNotAvailable => AsErrorKindImpl::AddrNotAvailable,
373        io::ErrorKind::NetworkDown => AsErrorKindImpl::NetworkDown,
374        io::ErrorKind::BrokenPipe => AsErrorKindImpl::BrokenPipe,
375        io::ErrorKind::AlreadyExists => AsErrorKindImpl::AlreadyExists,
376        io::ErrorKind::WouldBlock => AsErrorKindImpl::WouldBlock,
377        io::ErrorKind::NotADirectory => AsErrorKindImpl::NotADirectory,
378        io::ErrorKind::IsADirectory => AsErrorKindImpl::IsADirectory,
379        io::ErrorKind::DirectoryNotEmpty => AsErrorKindImpl::DirectoryNotEmpty,
380        io::ErrorKind::ReadOnlyFilesystem => AsErrorKindImpl::ReadOnlyFilesystem,
381        io::ErrorKind::StaleNetworkFileHandle => AsErrorKindImpl::StaleNetworkFileHandle,
382        io::ErrorKind::InvalidInput => AsErrorKindImpl::InvalidInput,
383        io::ErrorKind::InvalidData => AsErrorKindImpl::InvalidData,
384        io::ErrorKind::TimedOut => AsErrorKindImpl::TimedOut,
385        io::ErrorKind::WriteZero => AsErrorKindImpl::WriteZero,
386        io::ErrorKind::StorageFull => AsErrorKindImpl::StorageFull,
387        io::ErrorKind::NotSeekable => AsErrorKindImpl::NotSeekable,
388        io::ErrorKind::QuotaExceeded => AsErrorKindImpl::QuotaExceeded,
389        io::ErrorKind::FileTooLarge => AsErrorKindImpl::FileTooLarge,
390        io::ErrorKind::ResourceBusy => AsErrorKindImpl::ResourceBusy,
391        io::ErrorKind::ExecutableFileBusy => AsErrorKindImpl::ExecutableFileBusy,
392        io::ErrorKind::Deadlock => AsErrorKindImpl::Deadlock,
393        io::ErrorKind::CrossesDevices => AsErrorKindImpl::CrossesDevices,
394        io::ErrorKind::TooManyLinks => AsErrorKindImpl::TooManyLinks,
395        io::ErrorKind::InvalidFilename => AsErrorKindImpl::InvalidFilename,
396        io::ErrorKind::ArgumentListTooLong => AsErrorKindImpl::ArgumentListTooLong,
397        io::ErrorKind::Interrupted => AsErrorKindImpl::Interrupted,
398        io::ErrorKind::Unsupported => AsErrorKindImpl::Unsupported,
399        io::ErrorKind::UnexpectedEof => AsErrorKindImpl::UnexpectedEof,
400        io::ErrorKind::OutOfMemory => AsErrorKindImpl::OutOfMemory,
401        io::ErrorKind::Other => AsErrorKindImpl::Other,
402        _ => AsErrorKindImpl::Other,
403    }
404}
405
406fn de_error_kind(kind: AsErrorKindImpl) -> Result<io::ErrorKind, Infallible> {
407    Ok(match kind {
408        AsErrorKindImpl::NotFound => io::ErrorKind::NotFound,
409        AsErrorKindImpl::PermissionDenied => io::ErrorKind::PermissionDenied,
410        AsErrorKindImpl::ConnectionRefused => io::ErrorKind::ConnectionRefused,
411        AsErrorKindImpl::ConnectionReset => io::ErrorKind::ConnectionReset,
412        AsErrorKindImpl::HostUnreachable => io::ErrorKind::HostUnreachable,
413        AsErrorKindImpl::NetworkUnreachable => io::ErrorKind::NetworkUnreachable,
414        AsErrorKindImpl::ConnectionAborted => io::ErrorKind::ConnectionAborted,
415        AsErrorKindImpl::NotConnected => io::ErrorKind::NotConnected,
416        AsErrorKindImpl::AddrInUse => io::ErrorKind::AddrInUse,
417        AsErrorKindImpl::AddrNotAvailable => io::ErrorKind::AddrNotAvailable,
418        AsErrorKindImpl::NetworkDown => io::ErrorKind::NetworkDown,
419        AsErrorKindImpl::BrokenPipe => io::ErrorKind::BrokenPipe,
420        AsErrorKindImpl::AlreadyExists => io::ErrorKind::AlreadyExists,
421        AsErrorKindImpl::WouldBlock => io::ErrorKind::WouldBlock,
422        AsErrorKindImpl::NotADirectory => io::ErrorKind::NotADirectory,
423        AsErrorKindImpl::IsADirectory => io::ErrorKind::IsADirectory,
424        AsErrorKindImpl::DirectoryNotEmpty => io::ErrorKind::DirectoryNotEmpty,
425        AsErrorKindImpl::ReadOnlyFilesystem => io::ErrorKind::ReadOnlyFilesystem,
426        AsErrorKindImpl::StaleNetworkFileHandle => io::ErrorKind::StaleNetworkFileHandle,
427        AsErrorKindImpl::InvalidInput => io::ErrorKind::InvalidInput,
428        AsErrorKindImpl::InvalidData => io::ErrorKind::InvalidData,
429        AsErrorKindImpl::TimedOut => io::ErrorKind::TimedOut,
430        AsErrorKindImpl::WriteZero => io::ErrorKind::WriteZero,
431        AsErrorKindImpl::StorageFull => io::ErrorKind::StorageFull,
432        AsErrorKindImpl::NotSeekable => io::ErrorKind::NotSeekable,
433        AsErrorKindImpl::QuotaExceeded => io::ErrorKind::QuotaExceeded,
434        AsErrorKindImpl::FileTooLarge => io::ErrorKind::FileTooLarge,
435        AsErrorKindImpl::ResourceBusy => io::ErrorKind::ResourceBusy,
436        AsErrorKindImpl::ExecutableFileBusy => io::ErrorKind::ExecutableFileBusy,
437        AsErrorKindImpl::Deadlock => io::ErrorKind::Deadlock,
438        AsErrorKindImpl::CrossesDevices => io::ErrorKind::CrossesDevices,
439        AsErrorKindImpl::TooManyLinks => io::ErrorKind::TooManyLinks,
440        AsErrorKindImpl::InvalidFilename => io::ErrorKind::InvalidFilename,
441        AsErrorKindImpl::ArgumentListTooLong => io::ErrorKind::ArgumentListTooLong,
442        AsErrorKindImpl::Interrupted => io::ErrorKind::Interrupted,
443        AsErrorKindImpl::Unsupported => io::ErrorKind::Unsupported,
444        AsErrorKindImpl::UnexpectedEof => io::ErrorKind::UnexpectedEof,
445        AsErrorKindImpl::OutOfMemory => io::ErrorKind::OutOfMemory,
446        AsErrorKindImpl::Other => io::ErrorKind::Other,
447    })
448}
449
450serde_conv!(pub AsErrorKind, io::ErrorKind, ser_error_kind, de_error_kind);
451
452#[serde_as]
453#[derive(Serialize, Deserialize)]
454pub struct AsIoErrorImpl {
455    #[serde_as(as = "AsErrorKind")]
456    pub kind: io::ErrorKind,
457    pub msg: String,
458}
459
460fn ser_io_error(error: &io::Error) -> AsIoErrorImpl {
461    AsIoErrorImpl {
462        kind: error.kind(),
463        msg: error.to_string(),
464    }
465}
466
467fn de_io_error(error: AsIoErrorImpl) -> Result<io::Error, Infallible> {
468    Ok(io::Error::new(error.kind, error.msg))
469}
470
471serde_conv!(pub AsIoError, io::Error, ser_io_error, de_io_error);
472
473serde_conv!(
474    pub AsAnyhow,
475    anyhow::Error,
476    |error: &anyhow::Error| error.to_string(),
477    |error: String| Ok::<_, Infallible>(anyhow::Error::msg(error))
478);
479
480#[derive(Serialize, Deserialize)]
481pub enum AsPresignerErrorImpl {
482    VerificationFailure,
483}
484
485fn ser_presigner_error(error: &PresignerError) -> AsPresignerErrorImpl {
486    match error {
487        PresignerError::VerificationFailure => AsPresignerErrorImpl::VerificationFailure,
488    }
489}
490
491fn de_presigner_error(error: AsPresignerErrorImpl) -> Result<PresignerError, Infallible> {
492    Ok(match error {
493        AsPresignerErrorImpl::VerificationFailure => PresignerError::VerificationFailure,
494    })
495}
496
497serde_conv!(
498    AsPresignerError,
499    PresignerError,
500    ser_presigner_error,
501    de_presigner_error
502);
503
504#[serde_as]
505#[derive(Serialize, Deserialize)]
506pub enum AsSignerErrorImpl {
507    KeypairPubkeyMismatch,
508    NotEnoughSigners,
509    TransactionError(TransactionError),
510    Custom(String),
511    PresignerError(#[serde_as(as = "AsPresignerError")] PresignerError),
512    Connection(String),
513    InvalidInput(String),
514    NoDeviceFound,
515    Protocol(String),
516    UserCancel(String),
517    TooManySigners,
518}
519
520fn ser_signer_error(error: &SignerError) -> AsSignerErrorImpl {
521    match clone_signer_error(error) {
522        SignerError::KeypairPubkeyMismatch => AsSignerErrorImpl::KeypairPubkeyMismatch,
523        SignerError::NotEnoughSigners => AsSignerErrorImpl::NotEnoughSigners,
524        SignerError::TransactionError(transaction_error) => {
525            AsSignerErrorImpl::TransactionError(transaction_error)
526        }
527        SignerError::Custom(error) => AsSignerErrorImpl::Custom(error),
528        SignerError::PresignerError(presigner_error) => {
529            AsSignerErrorImpl::PresignerError(presigner_error)
530        }
531        SignerError::Connection(error) => AsSignerErrorImpl::Connection(error),
532        SignerError::InvalidInput(error) => AsSignerErrorImpl::InvalidInput(error),
533        SignerError::NoDeviceFound => AsSignerErrorImpl::NoDeviceFound,
534        SignerError::Protocol(error) => AsSignerErrorImpl::Protocol(error),
535        SignerError::UserCancel(error) => AsSignerErrorImpl::UserCancel(error),
536        SignerError::TooManySigners => AsSignerErrorImpl::TooManySigners,
537    }
538}
539
540fn de_signer_error(error: AsSignerErrorImpl) -> Result<SignerError, Infallible> {
541    Ok(match error {
542        AsSignerErrorImpl::KeypairPubkeyMismatch => SignerError::KeypairPubkeyMismatch,
543        AsSignerErrorImpl::NotEnoughSigners => SignerError::NotEnoughSigners,
544        AsSignerErrorImpl::TransactionError(transaction_error) => {
545            SignerError::TransactionError(transaction_error)
546        }
547        AsSignerErrorImpl::Custom(error) => SignerError::Custom(error),
548        AsSignerErrorImpl::PresignerError(presigner_error) => {
549            SignerError::PresignerError(presigner_error)
550        }
551        AsSignerErrorImpl::Connection(error) => SignerError::Connection(error),
552        AsSignerErrorImpl::InvalidInput(error) => SignerError::InvalidInput(error),
553        AsSignerErrorImpl::NoDeviceFound => SignerError::NoDeviceFound,
554        AsSignerErrorImpl::Protocol(error) => SignerError::Protocol(error),
555        AsSignerErrorImpl::UserCancel(error) => SignerError::UserCancel(error),
556        AsSignerErrorImpl::TooManySigners => SignerError::TooManySigners,
557    })
558}
559
560serde_conv!(
561    pub AsSignerError,
562    SignerError,
563    ser_signer_error,
564    de_signer_error
565);
566
567fn clone_rpc_response_error(data: &RpcResponseErrorData) -> RpcResponseErrorData {
568    match data {
569        RpcResponseErrorData::Empty => RpcResponseErrorData::Empty,
570        RpcResponseErrorData::SendTransactionPreflightFailure(result) => {
571            RpcResponseErrorData::SendTransactionPreflightFailure(result.clone())
572        }
573        RpcResponseErrorData::NodeUnhealthy { num_slots_behind } => {
574            RpcResponseErrorData::NodeUnhealthy {
575                num_slots_behind: *num_slots_behind,
576            }
577        }
578    }
579}
580
581fn clone_rpc_error(error: &RpcError) -> RpcError {
582    match error {
583        RpcError::RpcRequestError(error) => RpcError::RpcRequestError(error.clone()),
584        RpcError::RpcResponseError {
585            code,
586            message,
587            data,
588        } => RpcError::RpcResponseError {
589            code: *code,
590            message: message.clone(),
591            data: clone_rpc_response_error(data),
592        },
593        RpcError::ParseError(error) => RpcError::ParseError(error.clone()),
594        RpcError::ForUser(error) => RpcError::ForUser(error.clone()),
595    }
596}
597
598fn clone_presigner_error(error: &PresignerError) -> PresignerError {
599    match error {
600        PresignerError::VerificationFailure => PresignerError::VerificationFailure,
601    }
602}
603
604fn clone_signer_error(error: &SignerError) -> SignerError {
605    match error {
606        SignerError::KeypairPubkeyMismatch => SignerError::KeypairPubkeyMismatch,
607        SignerError::NotEnoughSigners => SignerError::NotEnoughSigners,
608        SignerError::TransactionError(error) => SignerError::TransactionError(error.clone()),
609        SignerError::Custom(error) => SignerError::Custom(error.clone()),
610        SignerError::PresignerError(error) => {
611            SignerError::PresignerError(clone_presigner_error(error))
612        }
613        SignerError::Connection(error) => SignerError::Connection(error.clone()),
614        SignerError::InvalidInput(error) => SignerError::InvalidInput(error.clone()),
615        SignerError::NoDeviceFound => SignerError::NoDeviceFound,
616        SignerError::Protocol(error) => SignerError::Protocol(error.clone()),
617        SignerError::UserCancel(error) => SignerError::UserCancel(error.clone()),
618        SignerError::TooManySigners => SignerError::TooManySigners,
619    }
620}
621
622fn ser_kind(kind: &ClientErrorKind) -> AsClientErrorKindImpl {
623    match kind {
624        ClientErrorKind::Io(error) => {
625            AsClientErrorKindImpl::Io(io::Error::new(error.kind(), error.to_string()))
626        }
627        ClientErrorKind::Reqwest(error) => AsClientErrorKindImpl::Custom(error.to_string()),
628        ClientErrorKind::Middleware(error) => {
629            AsClientErrorKindImpl::Middleware(anyhow!(format!("{:#}", error)))
630        }
631        ClientErrorKind::RpcError(error) => AsClientErrorKindImpl::RpcError(clone_rpc_error(error)),
632        ClientErrorKind::SerdeJson(error) => AsClientErrorKindImpl::Custom(error.to_string()),
633        ClientErrorKind::SigningError(error) => {
634            AsClientErrorKindImpl::SigningError(clone_signer_error(error))
635        }
636        ClientErrorKind::TransactionError(error) => {
637            AsClientErrorKindImpl::TransactionError(error.clone())
638        }
639        ClientErrorKind::Custom(error) => AsClientErrorKindImpl::Custom(error.clone()),
640    }
641}
642
643fn de_kind(kind: AsClientErrorKindImpl) -> Result<ClientErrorKind, Infallible> {
644    Ok(match kind {
645        AsClientErrorKindImpl::Io(error) => ClientErrorKind::Io(error),
646        AsClientErrorKindImpl::Middleware(error) => ClientErrorKind::Middleware(error),
647        AsClientErrorKindImpl::RpcError(rpc_error) => ClientErrorKind::RpcError(rpc_error),
648        AsClientErrorKindImpl::SigningError(signer_error) => {
649            ClientErrorKind::SigningError(signer_error)
650        }
651        AsClientErrorKindImpl::TransactionError(transaction_error) => {
652            ClientErrorKind::TransactionError(transaction_error)
653        }
654        AsClientErrorKindImpl::Custom(error) => ClientErrorKind::Custom(error),
655    })
656}
657
658serde_conv!(pub AsClientErrorKind, ClientErrorKind, ser_kind, de_kind);
659
660#[serde_as]
661#[derive(Serialize, Deserialize)]
662pub struct AsClientErrorImpl {
663    #[serde_as(as = "Option<AsRpcRequest>")]
664    pub request: Option<RpcRequest>,
665    #[serde_as(as = "Box<AsClientErrorKind>")]
666    pub kind: Box<ClientErrorKind>,
667}
668
669fn clone_client_error_kind(kind: &ClientErrorKind) -> Box<ClientErrorKind> {
670    Box::new(de_kind(ser_kind(kind)).unwrap())
671}
672
673fn ser_client_error(error: &ClientError) -> AsClientErrorImpl {
674    AsClientErrorImpl {
675        request: error.request.clone(),
676        kind: clone_client_error_kind(&error.kind),
677    }
678}
679
680fn de_client_error(error: AsClientErrorImpl) -> Result<ClientError, Infallible> {
681    Ok(ClientError {
682        request: error.request,
683        kind: error.kind,
684    })
685}
686
687serde_conv!(
688    pub AsClientError,
689    ClientError,
690    ser_client_error,
691    de_client_error
692);
693
694#[derive(Serialize, Deserialize)]
695pub enum AsCompileErrorImpl {
696    AccountIndexOverflow,
697    AddressTableLookupIndexOverflow,
698    UnknownInstructionKey(Pubkey),
699}
700
701fn ser_CompileError(error: &CompileError) -> AsCompileErrorImpl {
702    match error {
703        CompileError::AccountIndexOverflow => AsCompileErrorImpl::AccountIndexOverflow,
704        CompileError::AddressTableLookupIndexOverflow => {
705            AsCompileErrorImpl::AddressTableLookupIndexOverflow
706        }
707        CompileError::UnknownInstructionKey(pubkey) => {
708            AsCompileErrorImpl::UnknownInstructionKey(*pubkey)
709        }
710    }
711}
712
713fn de_CompileError(error: AsCompileErrorImpl) -> Result<CompileError, Infallible> {
714    Ok(match error {
715        AsCompileErrorImpl::AccountIndexOverflow => CompileError::AccountIndexOverflow,
716        AsCompileErrorImpl::AddressTableLookupIndexOverflow => {
717            CompileError::AddressTableLookupIndexOverflow
718        }
719        AsCompileErrorImpl::UnknownInstructionKey(pubkey) => {
720            CompileError::UnknownInstructionKey(pubkey)
721        }
722    })
723}
724
725serde_conv!(pub AsCompileError, CompileError, ser_CompileError, de_CompileError);
726
727#[derive(Serialize, Deserialize)]
728pub enum AsSanitizeErrorImpl {
729    IndexOutOfBounds,
730    ValueOutOfBounds,
731    InvalidValue,
732}
733
734fn ser_SanitizeError(error: &SanitizeError) -> AsSanitizeErrorImpl {
735    match error {
736        SanitizeError::IndexOutOfBounds => AsSanitizeErrorImpl::IndexOutOfBounds,
737        SanitizeError::ValueOutOfBounds => AsSanitizeErrorImpl::ValueOutOfBounds,
738        SanitizeError::InvalidValue => AsSanitizeErrorImpl::InvalidValue,
739    }
740}
741
742fn de_SanitizeError(error: AsSanitizeErrorImpl) -> Result<SanitizeError, Infallible> {
743    Ok(match error {
744        AsSanitizeErrorImpl::IndexOutOfBounds => SanitizeError::IndexOutOfBounds,
745        AsSanitizeErrorImpl::ValueOutOfBounds => SanitizeError::ValueOutOfBounds,
746        AsSanitizeErrorImpl::InvalidValue => SanitizeError::InvalidValue,
747    })
748}
749
750serde_conv!(pub AsSanitizeError, SanitizeError, ser_SanitizeError, de_SanitizeError);
751
752#[derive(Serialize, Deserialize)]
753pub enum AsMailboxErrorImpl {
754    Closed,
755    Timeout,
756}
757
758fn ser_MailboxError(error: &MailboxError) -> AsMailboxErrorImpl {
759    match error {
760        MailboxError::Closed => AsMailboxErrorImpl::Closed,
761        MailboxError::Timeout => AsMailboxErrorImpl::Timeout,
762    }
763}
764
765fn de_MailboxError(error: AsMailboxErrorImpl) -> Result<MailboxError, Infallible> {
766    Ok(match error {
767        AsMailboxErrorImpl::Closed => MailboxError::Closed,
768        AsMailboxErrorImpl::Timeout => MailboxError::Timeout,
769    })
770}
771
772serde_conv!(pub AsMailboxError, MailboxError, ser_MailboxError, de_MailboxError);
773
774serde_conv!(pub AsCancelled, Canceled, |_| (), |_: ()| Ok::<_, Infallible>(Canceled));