dag/
errors.rs

1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8use std::io;
9
10use thiserror::Error;
11
12use crate::Group;
13use crate::Id;
14use crate::VertexName;
15
16/// Error used by the Dag crate.
17#[derive(Debug, Error)]
18pub enum DagError {
19    /// A vertex name cannot be found.
20    #[error("{0:?} cannot be found")]
21    VertexNotFound(VertexName),
22
23    /// An Id cannot be found.
24    #[error("{0:?} cannot be found")]
25    IdNotFound(Id),
26
27    /// A fast path cannot be used.
28    #[error("NeedSlowPath: {0}")]
29    NeedSlowPath(String),
30
31    /// Callsite does something wrong. For example, a "parent function" does not
32    /// return reproducible results for a same vertex if called twice.
33    #[error("ProgrammingError: {0}")]
34    Programming(String),
35
36    /// Logic error in this crate. A bug in this crate or the backend data.
37    #[error("bug: {0}")]
38    Bug(String),
39
40    /// The backend (ex. filesystem) cannot fulfill the request somehow.
41    #[error(transparent)]
42    Backend(Box<BackendError>),
43
44    /// No space for new Ids.
45    #[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    /// Other source of backend errors. Useful for external crates implementing
62    /// traits of the `dag` crate.
63    #[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
86/// Quick way to return a `BackendError::Generic` error.
87pub fn bug<T>(message: impl ToString) -> crate::Result<T> {
88    Err(DagError::Bug(message.to_string()))
89}
90
91/// Quick way to return a `Programming` error.
92pub 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}