use std::fmt;
use std::path::PathBuf;
#[derive(Debug)]
pub(crate) enum ProcessError {
Spawn {
program: String,
directory: PathBuf,
source: std::io::Error,
},
Failed {
program: String,
directory: PathBuf,
status: std::process::ExitStatus,
},
FailedOutput {
program: String,
directory: PathBuf,
status: std::process::ExitStatus,
output: String,
},
Wait {
program: String,
source: std::io::Error,
},
Signal(std::io::Error),
Inspect {
path: PathBuf,
source: std::io::Error,
},
Readiness {
service: &'static str,
address: String,
},
Terminate {
program: &'static str,
source: std::io::Error,
},
}
impl fmt::Display for ProcessError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Spawn {
program,
directory,
source,
} => write!(
formatter,
"cannot start `{program}` in {}: {source}",
directory.display()
),
Self::Failed {
program,
directory,
status,
} => write!(
formatter,
"command `{program}` failed with {status}\n\nproject:\n {}\n\nrerun directly from that directory",
directory.display()
),
Self::FailedOutput {
program,
directory,
status,
output,
} => write!(
formatter,
"command `{program}` failed with {status}\n\nproject:\n {}\n\noutput:\n{output}",
directory.display()
),
Self::Wait { program, source } => {
write!(formatter, "cannot wait for `{program}`: {source}")
}
Self::Signal(error) => write!(
formatter,
"cannot install process shutdown handler: {error}"
),
Self::Inspect { path, source } => write!(
formatter,
"cannot inspect watched path {}: {source}",
path.display()
),
Self::Readiness { service, address } => write!(
formatter,
"{service} did not become ready at {address} before the startup timeout"
),
Self::Terminate { program, source } => {
write!(formatter, "cannot terminate supervised {program}: {source}")
}
}
}
}
impl std::error::Error for ProcessError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Spawn { source, .. }
| Self::Wait { source, .. }
| Self::Inspect { source, .. }
| Self::Terminate { source, .. } => Some(source),
Self::Signal(error) => Some(error),
Self::Failed { .. } | Self::FailedOutput { .. } | Self::Readiness { .. } => None,
}
}
}