1use std::fmt;
2
3#[derive(Debug)]
11pub enum EngineError {
12 CommandFailed {
13 task: String,
14 step: usize,
15 total: usize,
16 command: String,
17 reason: String,
18 },
19 CommandBlockFailed {
20 task: String,
21 step: usize,
22 total: usize,
23 reason: String,
24 },
25 CommandBlockStartFailed {
26 shell: String,
27 source: Box<EngineError>,
28 },
29 Interpolation(String),
30 ShellNotFound(String),
31 UnsupportedShell(String),
32 Runtime(String),
33 Io {
34 message: &'static str,
35 path: String,
36 source: std::io::Error,
37 },
38}
39
40impl fmt::Display for EngineError {
41 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42 match self {
43 Self::CommandFailed {
44 task,
45 step,
46 total,
47 command: _,
48 reason,
49 } => write!(
50 f,
51 "task '{task}' failed at step [{step}/{total}] with {}",
52 reason
53 ),
54 Self::CommandBlockFailed {
55 task,
56 step,
57 total,
58 reason,
59 } => write!(
60 f,
61 "task '{task}' failed at step [{step}/{total}] with {}",
62 reason
63 ),
64 Self::CommandBlockStartFailed { shell, source } => {
65 write!(
66 f,
67 "could not start command block with shell '{shell}'\n{source}"
68 )
69 }
70 Self::Interpolation(message) => f.write_str(message),
71 Self::ShellNotFound(message) => f.write_str(message),
72 Self::UnsupportedShell(shell) => write!(f, "shell '{shell}' is not supported"),
73 Self::Runtime(message) => f.write_str(message),
74 Self::Io {
75 message,
76 path,
77 source,
78 } => write!(f, "{message}: {path}: {source}"),
79 }
80 }
81}
82
83pub(crate) fn command_block_failed(
84 task: &str,
85 step_index: usize,
86 step_total: usize,
87 reason: &str,
88) -> EngineError {
89 EngineError::CommandBlockFailed {
90 task: task.to_string(),
91 step: step_index,
92 total: step_total,
93 reason: reason.to_string(),
94 }
95}
96
97impl std::error::Error for EngineError {
98 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
99 match self {
100 Self::Io { source, .. } => Some(source),
101 Self::CommandBlockStartFailed { source, .. } => Some(source.as_ref()),
102 _ => None,
103 }
104 }
105}
106
107pub(crate) fn command_block_start_failed(shell: &str, source: EngineError) -> EngineError {
108 match source {
109 EngineError::ShellNotFound(_)
110 | EngineError::UnsupportedShell(_)
111 | EngineError::Io { .. } => EngineError::CommandBlockStartFailed {
112 shell: shell.to_string(),
113 source: Box::new(source),
114 },
115 other => other,
116 }
117}
118
119pub(crate) fn command_failed(
120 task: &str,
121 step_index: usize,
122 step_total: usize,
123 command: &str,
124 reason: &str,
125) -> EngineError {
126 EngineError::CommandFailed {
127 task: task.to_string(),
128 step: step_index,
129 total: step_total,
130 command: command.to_string(),
131 reason: reason.to_string(),
132 }
133}