light-client 0.23.0

Client library for Light Protocol
Documentation
use thiserror::Error;

#[derive(Error, Debug, PartialEq)]
pub enum IndexerError {
    #[error("Photon API error in {context}: {message}")]
    PhotonError { context: String, message: String },

    #[error("RPC error: {0}")]
    RpcError(String),

    #[error("Failed to deserialize account data: {0}")]
    DeserializeError(#[from] solana_program_error::ProgramError),

    #[error("API error: {0}")]
    ApiError(String),

    #[error("Missing result from {context}: {message}")]
    MissingResult { context: String, message: String },

    #[error("Account not found")]
    AccountNotFound,

    #[error("Base58 decode error: {field} - {message}")]
    Base58DecodeError { field: String, message: String },

    #[error("Invalid parameters: {0}")]
    InvalidParameters(String),

    #[error("Data decode error: {field} - {message}")]
    DataDecodeError { field: String, message: String },

    #[error("Method not implemented: {0}")]
    NotImplemented(String),

    #[error("Unknown error: {0}")]
    Unknown(String),

    #[error("Indexed Merkle tree reference v1 error: {0}")]
    ReferenceIndexedMerkleTreeError(
        #[from] light_indexed_merkle_tree::reference::IndexedReferenceMerkleTreeError,
    ),
    #[error("Indexed Merkle tree v1 error: {0}")]
    IndexedMerkleTreeError(#[from] light_indexed_merkle_tree::errors::IndexedMerkleTreeError),
    #[error("Invalid response data")]
    InvalidResponseData,

    #[error("Error: `{0}`")]
    CustomError(String),
    #[error(
        "Indexer not initialized. Set photon_url in LightClientConfig to enable indexer API calls."
    )]
    NotInitialized,
    #[error("Indexer slot has not reached the requested slot.")]
    IndexerNotSyncedToSlot,
    #[error("Address Merkle trees cannot be packed as output Merkle trees.")]
    InvalidPackTreeType,
    #[error("Cannot mix v1 and v2 trees in the same validity proof. State tree version: {state_version}, Address tree version: {address_version}")]
    MixedTreeVersions {
        state_version: String,
        address_version: String,
    },
}

impl IndexerError {
    pub fn missing_result(context: impl Into<String>, message: impl Into<String>) -> Self {
        Self::MissingResult {
            context: context.into(),
            message: message.into(),
        }
    }

    pub fn api_error(error: impl std::fmt::Display) -> Self {
        Self::ApiError(error.to_string())
    }

    pub fn decode_error(field: impl Into<String>, error: impl std::fmt::Display) -> Self {
        Self::DataDecodeError {
            field: field.into(),
            message: error.to_string(),
        }
    }

    pub fn base58_decode_error(field: impl Into<String>, error: impl std::fmt::Display) -> Self {
        Self::Base58DecodeError {
            field: field.into(),
            message: error.to_string(),
        }
    }
}

impl<T> From<photon_api::apis::Error<T>> for IndexerError {
    fn from(error: photon_api::apis::Error<T>) -> Self {
        IndexerError::ApiError(error.to_string())
    }
}

impl From<crate::rpc::RpcError> for IndexerError {
    fn from(error: crate::rpc::RpcError) -> Self {
        IndexerError::RpcError(error.to_string())
    }
}

impl Clone for IndexerError {
    fn clone(&self) -> Self {
        match self {
            IndexerError::PhotonError { context, message } => IndexerError::PhotonError {
                context: context.clone(),
                message: message.clone(),
            },
            IndexerError::RpcError(message) => IndexerError::RpcError(message.clone()),
            IndexerError::DeserializeError(err) => IndexerError::DeserializeError(err.clone()),
            IndexerError::ApiError(message) => IndexerError::ApiError(message.clone()),
            IndexerError::MissingResult { context, message } => IndexerError::MissingResult {
                context: context.clone(),
                message: message.clone(),
            },
            IndexerError::AccountNotFound => IndexerError::AccountNotFound,
            IndexerError::Base58DecodeError { field, message } => IndexerError::Base58DecodeError {
                field: field.clone(),
                message: message.clone(),
            },
            IndexerError::InvalidParameters(message) => {
                IndexerError::InvalidParameters(message.clone())
            }
            IndexerError::DataDecodeError { field, message } => IndexerError::DataDecodeError {
                field: field.clone(),
                message: message.clone(),
            },
            IndexerError::NotImplemented(message) => IndexerError::NotImplemented(message.clone()),
            IndexerError::Unknown(message) => IndexerError::Unknown(message.clone()),
            IndexerError::ReferenceIndexedMerkleTreeError(_) => {
                IndexerError::CustomError("ReferenceIndexedMerkleTreeError".to_string())
            }
            IndexerError::IndexedMerkleTreeError(_) => {
                IndexerError::CustomError("IndexedMerkleTreeError".to_string())
            }
            IndexerError::InvalidResponseData => IndexerError::InvalidResponseData,
            IndexerError::CustomError(_) => IndexerError::CustomError("IndexerError".to_string()),
            IndexerError::NotInitialized => IndexerError::NotInitialized,
            IndexerError::IndexerNotSyncedToSlot => IndexerError::IndexerNotSyncedToSlot,
            IndexerError::InvalidPackTreeType => IndexerError::InvalidPackTreeType,
            IndexerError::MixedTreeVersions {
                state_version,
                address_version,
            } => IndexerError::MixedTreeVersions {
                state_version: state_version.clone(),
                address_version: address_version.clone(),
            },
        }
    }
}