use super::HeadInfo;
use crate::prelude::StateMutationError;
use crate::query::StateQueryError;
use crate::scratch::ScratchError;
use crate::scratch::SyncScratchError;
use holo_hash::ActionHash;
use holo_hash::EntryHash;
use holochain_serialized_bytes::prelude::*;
use holochain_sqlite::error::DatabaseError;
use holochain_types::prelude::*;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum SourceChainError {
#[error("The source chain is empty, but is expected to have been initialized")]
ChainEmpty,
#[error("Agent key {0} invalid in cell {1}")]
InvalidAgentKey(AgentPubKey, CellId),
#[error(
"Attempted to commit a bundle to the source chain, but the source chain head has moved since the bundle began. Bundle head: {2:?}, Current head: {3:?}"
)]
HeadMoved(
Box<Vec<SignedActionHashed>>,
Box<Vec<EntryHashed>>,
Option<ActionHash>,
Option<HeadInfo>,
),
#[error(transparent)]
TimestampError(#[from] holochain_zome_types::prelude::TimestampError),
#[error(transparent)]
ScratchError(#[from] ScratchError),
#[error("Attempted to write anything other than the countersigning session entry while the chain was locked for a countersigning session.")]
ChainLocked,
#[error("Attempted to write a countersigning session that has already expired")]
LockExpired,
#[error("Attempted to write anything other than the countersigning session entry at the same time as the session entry.")]
DirtyCounterSigningWrite,
#[error("Attempted to write a countersigning session when there is no active session.")]
CountersigningWriteWithoutSession,
#[error(
"The source chain's structure is invalid. This error is not recoverable. Detail:\n{0}"
)]
InvalidStructure(ChainInvalidReason),
#[error("Serialization error: {0}")]
SerializationError(#[from] SerializedBytesError),
#[error("Workspace error: {0}")]
DatabaseError(#[from] DatabaseError),
#[error("SerdeJson Error: {0}")]
SerdeJsonError(String),
#[error("Record signature is invalid")]
InvalidSignature,
#[error("InvalidCommit error: {0}")]
InvalidCommit(String),
#[error("The commit could not be completed but may be retried: {0:?}")]
IncompleteCommit(IncompleteCommitReason),
#[error("KeystoreError: {0}")]
KeystoreError(#[from] holochain_keystore::KeystoreError),
#[error(transparent)]
DhtOpError(#[from] DhtOpError),
#[error(transparent)]
StateMutationError(#[from] StateMutationError),
#[error(transparent)]
StateQueryError(#[from] StateQueryError),
#[error(transparent)]
SyncScratchError(#[from] SyncScratchError),
#[error(transparent)]
CounterSigningError(#[from] CounterSigningError),
#[error("The source chain was missing for a host call that requires it.")]
SourceChainMissing,
#[error("Other: {0}")]
Other(Box<dyn std::error::Error + Send + Sync>),
}
impl SourceChainError {
pub fn other(e: impl Into<Box<dyn std::error::Error + Send + Sync>>) -> Self {
Self::Other(e.into())
}
}
impl From<serde_json::Error> for SourceChainError {
fn from(e: serde_json::Error) -> Self {
Self::SerdeJsonError(format!("{e:?}"))
}
}
impl From<one_err::OneErr> for SourceChainError {
fn from(e: one_err::OneErr) -> Self {
Self::other(e)
}
}
#[derive(Error, Debug, PartialEq, Eq)]
pub enum ChainInvalidReason {
#[error("A valid chain always begins with a Dna entry, followed by an Agent entry.")]
GenesisDataMissing,
#[error("A genesis record contains incorrect data.")]
MalformedGenesisData,
#[error("A chain action and its corresponding entry have a discrepancy. Entry address: {0}")]
ActionAndEntryMismatch(EntryHash),
#[error("Content was expected to definitely exist at this address, but didn't: {0}")]
MissingData(EntryHash),
}
#[derive(Debug)]
pub enum IncompleteCommitReason {
DepMissingFromDht(Vec<AnyDhtHash>),
}
pub type SourceChainResult<T> = Result<T, SourceChainError>;