1use crate::{
2 build_graph::BuildGraphError,
3 compile::CompileError,
4 infrastructure::{CommandError, ConsoleError, DatabaseError, FileError},
5 ir::Build,
6 parse::ParseError,
7};
8use alloc::sync::Arc;
9use thiserror::Error;
10use tokio::{io, sync::AcquireError, task::JoinError};
11
12#[derive(Clone, Debug, Eq, Error, PartialEq)]
14pub enum BuildError {
15 #[error("{0}")]
17 Acquire(String),
18 #[error("build failed")]
20 Build,
21 #[error(transparent)]
23 BuildGraph(#[from] BuildGraphError),
24 #[error("build file dependency cycle detected")]
26 CircularModuleDependency,
27 #[error(transparent)]
29 Command(#[from] CommandError),
30 #[error(transparent)]
32 Compile(#[from] CompileError),
33 #[error(transparent)]
35 Console(#[from] ConsoleError),
36 #[error(transparent)]
38 Database(#[from] DatabaseError),
39 #[error("default output \"{0}\" not found")]
41 DefaultOutputNotFound(Arc<str>),
42 #[error(
44 "outputs {} not found in dynamic dependency file {}",
45 .0.outputs().join(", "),
46 .0.dynamic_module().unwrap()
47 )]
48 DynamicDependencyNotFound(Arc<Build>),
49 #[error(transparent)]
51 File(#[from] FileError),
52 #[error("file \"{0}\" not found")]
54 FileNotFound(String),
55 #[error("input \"{0}\" not built yet")]
57 InputNotBuilt(String),
58 #[error("input \"{0}\" not found")]
60 InputNotFound(String),
61 #[error("{0}")]
63 Io(String),
64 #[error("{0}")]
66 Join(String),
67 #[error("output \"{0}\" not found")]
69 OutputNotFound(String),
70 #[error(transparent)]
72 Parse(#[from] ParseError),
73}
74
75impl From<AcquireError> for BuildError {
76 fn from(error: AcquireError) -> Self {
77 Self::Acquire(error.to_string())
78 }
79}
80
81impl From<io::Error> for BuildError {
82 fn from(error: io::Error) -> Self {
83 Self::Io(error.to_string())
84 }
85}
86
87impl From<JoinError> for BuildError {
88 fn from(error: JoinError) -> Self {
89 Self::Join(error.to_string())
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[test]
98 fn display_acquire() {
99 assert_eq!(
100 BuildError::Acquire("semaphore closed".into()).to_string(),
101 "semaphore closed"
102 );
103 }
104
105 #[test]
106 fn display_dynamic_dependency_not_found() {
107 assert_eq!(
108 BuildError::DynamicDependencyNotFound(
109 Build::new(
110 vec!["foo".into(), "bar".into()],
111 vec![],
112 None,
113 vec![],
114 vec![],
115 Some("baz".into())
116 )
117 .into()
118 )
119 .to_string(),
120 "outputs foo, bar not found in dynamic dependency file baz"
121 );
122 }
123
124 #[test]
125 fn display_io() {
126 assert_eq!(
127 BuildError::Io("permission denied".into()).to_string(),
128 "permission denied"
129 );
130 }
131
132 #[test]
133 fn display_join() {
134 assert_eq!(
135 BuildError::Join("task cancelled".into()).to_string(),
136 "task cancelled"
137 );
138 }
139}