1use std::io;
9
10use thiserror::Error;
11
12use crate::Group;
13use crate::Id;
14use crate::VertexName;
15
16#[derive(Debug, Error)]
18pub enum DagError {
19    #[error("{0:?} cannot be found")]
21    VertexNotFound(VertexName),
22
23    #[error("{0:?} cannot be found")]
25    IdNotFound(Id),
26
27    #[error("NeedSlowPath: {0}")]
29    NeedSlowPath(String),
30
31    #[error("ProgrammingError: {0}")]
34    Programming(String),
35
36    #[error("bug: {0}")]
38    Bug(String),
39
40    #[error(transparent)]
42    Backend(Box<BackendError>),
43
44    #[error("out of space for group {0:?}")]
46    IdOverflow(Group),
47}
48
49#[derive(Debug, Error)]
50pub enum BackendError {
51    #[error("{0}")]
52    Generic(String),
53
54    #[error(transparent)]
55    Io(#[from] std::io::Error),
56
57    #[cfg(any(test, feature = "indexedlog-backend"))]
58    #[error(transparent)]
59    IndexedLog(#[from] indexedlog::Error),
60
61    #[error(transparent)]
64    Other(#[from] anyhow::Error),
65}
66
67impl From<BackendError> for DagError {
68    fn from(err: BackendError) -> DagError {
69        DagError::Backend(Box::new(err))
70    }
71}
72
73#[cfg(any(test, feature = "indexedlog-backend"))]
74impl From<indexedlog::Error> for DagError {
75    fn from(err: indexedlog::Error) -> DagError {
76        DagError::Backend(Box::new(BackendError::from(err)))
77    }
78}
79
80impl From<io::Error> for DagError {
81    fn from(err: io::Error) -> DagError {
82        DagError::Backend(Box::new(BackendError::from(err)))
83    }
84}
85
86pub fn bug<T>(message: impl ToString) -> crate::Result<T> {
88    Err(DagError::Bug(message.to_string()))
89}
90
91pub fn programming<T>(message: impl ToString) -> crate::Result<T> {
93    Err(DagError::Programming(message.to_string()))
94}
95
96pub trait NotFoundError {
97    fn not_found_error(&self) -> DagError;
98
99    fn not_found<T>(&self) -> crate::Result<T> {
100        Err(self.not_found_error())
101    }
102}
103
104impl NotFoundError for Id {
105    fn not_found_error(&self) -> DagError {
106        ::fail::fail_point!("dag-not-found-id");
107        DagError::IdNotFound(self.clone())
108    }
109}
110
111impl NotFoundError for VertexName {
112    fn not_found_error(&self) -> DagError {
113        ::fail::fail_point!("dag-not-found-vertex");
114        DagError::VertexNotFound(self.clone())
115    }
116}