Skip to main content

only_engine/
error.rs

1use std::fmt;
2use std::process::ExitCode;
3
4/// Engine-level runtime and host execution errors.
5///
6/// Args:
7/// None.
8///
9/// Returns:
10/// Stable typed error values for planner/runtime consumers.
11#[derive(Debug)]
12pub enum EngineError {
13    CommandFailed {
14        task: String,
15        step: usize,
16        total: usize,
17        command: String,
18        code: ExitCode,
19    },
20    Interpolation(String),
21    ShellNotFound(String),
22    UnsupportedShell(String),
23    Runtime(String),
24    Io {
25        message: &'static str,
26        path: String,
27        source: std::io::Error,
28    },
29}
30
31impl fmt::Display for EngineError {
32    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33        match self {
34            Self::CommandFailed {
35                task,
36                step,
37                total,
38                command,
39                code,
40            } => write!(
41                f,
42                "task '{task}' failed at step [{step}/{total}] while running `{command}` with exit code {code:?}"
43            ),
44            Self::Interpolation(message) => f.write_str(message),
45            Self::ShellNotFound(message) => f.write_str(message),
46            Self::UnsupportedShell(shell) => write!(f, "unsupported shell '{shell}'"),
47            Self::Runtime(message) => f.write_str(message),
48            Self::Io {
49                message,
50                path,
51                source,
52            } => write!(f, "{message}: {path}: {source}"),
53        }
54    }
55}
56
57impl std::error::Error for EngineError {
58    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
59        match self {
60            Self::Io { source, .. } => Some(source),
61            _ => None,
62        }
63    }
64}
65
66pub(crate) fn command_failed(
67    task: &str,
68    step_index: usize,
69    step_total: usize,
70    command: &str,
71    code: ExitCode,
72) -> EngineError {
73    EngineError::CommandFailed {
74        task: task.to_string(),
75        step: step_index,
76        total: step_total,
77        command: command.to_string(),
78        code,
79    }
80}