|
4 | 4 | /// When this error is encountered the cli will exit with the status code
|
5 | 5 | /// instead of printing an error,
|
6 | 6 | #[derive(Debug)]
|
7 |
| -pub struct ExitStatusError { |
8 |
| - status: Option<i32>, |
| 7 | +pub enum ExitStatusError { |
| 8 | + /// The subprocess exited with a specific exit code. |
| 9 | + ExitCode(i32), |
| 10 | + /// The subprocess was exited by a signal. Only available for `Unix` based systems. |
| 11 | + Signal(i32), |
| 12 | + /// Catchall for general errors. Error code `1` |
| 13 | + Unknown, |
9 | 14 | }
|
10 | 15 |
|
11 | 16 | impl ExitStatusError {
|
| 17 | + #[cfg(unix)] |
12 | 18 | pub(crate) fn new(status: std::process::ExitStatus) -> Self {
|
13 |
| - Self { |
14 |
| - status: status.code(), |
| 19 | + use std::os::unix::process::ExitStatusExt as _; |
| 20 | + |
| 21 | + if let Some(code) = status.code() { |
| 22 | + Self::ExitCode(code) |
| 23 | + } else if let Some(signal) = status.signal() { |
| 24 | + Self::Signal(signal) |
| 25 | + } else { |
| 26 | + Self::Unknown |
| 27 | + } |
| 28 | + } |
| 29 | + |
| 30 | + #[cfg(not(unix))] |
| 31 | + pub(crate) fn new(status: std::process::ExitStatus) -> Self { |
| 32 | + if let Some(code) = status.code() { |
| 33 | + Self::ExitCode(code) |
| 34 | + } else { |
| 35 | + Self::Unknown |
15 | 36 | }
|
16 | 37 | }
|
17 | 38 |
|
18 | 39 | pub fn code(&self) -> i32 {
|
19 |
| - self.status.unwrap_or(1) |
| 40 | + match self { |
| 41 | + Self::ExitCode(code) => *code, |
| 42 | + Self::Signal(signal) => 128 + *signal, |
| 43 | + Self::Unknown => 1, |
| 44 | + } |
| 45 | + .min(255) |
20 | 46 | }
|
21 | 47 | }
|
22 | 48 |
|
23 | 49 | impl std::error::Error for ExitStatusError {}
|
24 | 50 |
|
25 | 51 | impl std::fmt::Display for ExitStatusError {
|
26 | 52 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
27 |
| - let _ = write!(f, "subprocess exited with status: "); |
28 |
| - if let Some(status) = self.status { |
29 |
| - writeln!(f, "{status}") |
30 |
| - } else { |
31 |
| - writeln!(f, "unknown") |
| 53 | + let _ = write!(f, "subprocess exited with "); |
| 54 | + |
| 55 | + match self { |
| 56 | + Self::ExitCode(code) => write!(f, "exit code: {code}"), |
| 57 | + Self::Signal(signal) => write!(f, "signal: {signal}"), |
| 58 | + Self::Unknown => write!(f, "unknown status"), |
32 | 59 | }
|
33 | 60 | }
|
34 | 61 | }
|
0 commit comments