1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
//! Error types and implementations for [Invocation] interaction(s).
//!
//! [Invocation]: crate::Invocation
use crate::{
task::instruction::{Args, Input},
Unit,
};
use libipld::Ipld;
use serde::de::Error as DeError;
use std::io;
/// Generic error type for [Invocation] use cases.
///
/// [Invocation]: crate::Invocation
#[derive(thiserror::Error, Debug)]
pub enum Error<T> {
/// Error encoding structure to a [Cid].
///
/// [Cid]: libipld::cid::Cid
#[error("failed to encode CID: {0}")]
CidEncode(#[from] libipld::cid::Error),
/// Error thrown when condition or dynamic check is not met.
#[error("condition not met: {0}")]
ConditionNotMet(String),
/// Failure to decode/encode from/to DagCbor.
///
/// The underlying error is a [anyhow::Error], per the
/// [DagCborCodec] implementation.
///
/// [DagCborCodec]: libipld::cbor::DagCborCodec
#[error("failed to decode/encode DAG-CBOR: {0}")]
DagCborTranslation(#[from] anyhow::Error),
/// Error converting from [Ipld] structure via [serde].
///
/// Transparently forwards from [libipld::error::SerdeError]'s `source` and
/// `Display` methods through to an underlying error.
#[error("cannot convert from Ipld structure: {0}")]
FromIpld(#[from] libipld::error::SerdeError),
/// Invalid match discriminant or enumeration.
#[error("invalid discriminant {0:#?}")]
InvalidDiscriminant(T),
/// Error related to a missing a field in a structure or key
/// in a map.
#[error("no {0} field set")]
MissingField(String),
/// Error during parsing a [Url].
///
/// Transparently forwards from [url::ParseError]'s `source` and
/// `Display` methods through to an underlying error.
///
/// [Url]: url::Url
#[error(transparent)]
ParseResource(#[from] url::ParseError),
/// Generic unknown error.
#[error("unknown error")]
Unknown,
/// Unexpcted [Ipld] type.
#[error("unexpected Ipld type: {0:#?}")]
UnexpectedIpldType(Ipld),
/// Error when attempting to interpret a sequence of [u8]
/// as a string.
///
/// Transparently forwards from [std::str::Utf8Error]'s `source` and
/// `Display` methods through to an underlying error.
#[error(transparent)]
Utf8(#[from] std::str::Utf8Error),
/// Propagated IO error.
#[error("error writing data to console: {0}")]
Io(#[from] io::Error),
}
impl<T> Error<T> {
/// Return a [SerdeError] when returning an [Ipld] structure
/// that's not expected at the call-site.
///
/// [SerdeError]: libipld::error::SerdeError
pub fn unexpected_ipld(ipld: Ipld) -> Self {
Error::UnexpectedIpldType(ipld)
}
/// Return an `invalid type` [SerdeError] when not matching an expected
/// [Ipld] list/sequence type.
///
/// [SerdeError]: libipld::error::SerdeError
pub fn not_an_ipld_list() -> Self {
Error::FromIpld(libipld::error::SerdeError::invalid_type(
serde::de::Unexpected::Seq,
&"an Ipld list / sequence",
))
}
}
impl From<Error<Unit>> for Error<String> {
fn from(_err: Error<Unit>) -> Self {
Error::Unknown
}
}
impl From<Error<String>> for Error<Unit> {
fn from(_err: Error<String>) -> Error<Unit> {
Error::Unknown
}
}
impl<T> From<std::convert::Infallible> for Error<T> {
fn from(err: std::convert::Infallible) -> Self {
match err {}
}
}
/// Error type for parsing [Invocation] [Input]s.
///
/// [Invocation]: crate::Invocation
#[derive(thiserror::Error, Debug)]
pub enum InputParseError<T> {
/// Error converting from [Ipld] structure via [serde].
///
/// Transparently forwards from [libipld::error::SerdeError]'s `source` and
/// `Display` methods through to an underlying error.
#[error("cannot convert from Ipld structure: {0}")]
FromIpld(#[from] libipld::error::SerdeError),
/// Error converting from [Ipld] structure into [Args].
#[error("cannot convert from Ipld structure into arguments: {0:#?}")]
IpldToArgs(Args<T>),
/// Unexpected [Input] in [Task] structure.
///
/// [Task]: crate::Task
#[error("unexpected task input: {0:#?}")]
UnexpectedTaskInput(Input<T>),
/// Bubble-up conversion and other general [Invocation errors].
///
/// [Invocation errors]: Error
#[error(transparent)]
Invocation(#[from] Error<T>),
}
impl<T> From<std::convert::Infallible> for InputParseError<T> {
fn from(err: std::convert::Infallible) -> Self {
match err {}
}
}
/// Error type for resolving promised [Cid]s within [Invocation] [Input]s.
///
/// [Cid]: libipld::Cid
/// [Invocation]: crate::Invocation
#[derive(thiserror::Error, Debug)]
pub enum ResolveError {
/// Generic runtime error.
///
/// Transparently forwards from [anyhow::Error]'s `source` and
/// `Display` methods through to an underlying error.
#[error(transparent)]
Runtime(#[from] anyhow::Error),
/// Transport error when attempting to resolve [Invocation] [Input]'s [Cid].
///
/// [Cid]: libipld::Cid
/// [Invocation]: crate::Invocation
#[error("transport error during resolve phase of input Cid: {0}")]
Transport(String),
/// Unable to resolve a [Cid] within an [Invocation]'s [Input].
///
/// [Cid]: libipld::Cid
/// [Invocation]: crate::Invocation
#[error("error resolving input Cid: {0}")]
UnresolvedCid(String),
}
impl From<std::convert::Infallible> for ResolveError {
fn from(err: std::convert::Infallible) -> Self {
match err {}
}
}