1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#[cfg(doc)]
use crate::ShellTask;

use thiserror::Error as ThisError;

use std::{io, process::ExitStatus};

/// The result type used by a [`ShellTask`].
pub type Result<T> = std::result::Result<T, Error>;

/// The possible errors reported by a [`ShellTask`].
#[derive(ThisError, Debug)]
pub enum Error {
    /// This error occurs when a command exits with a status other than 0.
    #[error("'{task}' failed with {exit_status}.")]
    TaskFailure {
        /// The task that failed.
        task: String,

        /// The exit status that was returned.
        exit_status: ExitStatus,
    },

    /// This error occurs when a task could not be instantiated because it was malformed.
    /// This is a usage error, make sure you've typed the command correctly.
    #[error("'{task}' is not a valid command because {reason}.")]
    InvalidTask {
        /// The malformed task.
        task: String,

        /// The reason the task was malformed.
        reason: String,
    },

    /// This error occurs when a task could not spawn. Originates from [`std::process::Command::spawn`].
    #[error("could not spawn '{task}': {source}.")]
    CouldNotSpawn {
        /// The task that could not spawn.
        task: String,

        /// The [`io::Error`] that was reported by [`std::process::Command::spawn`].
        source: io::Error,
    },

    /// There was an error waiting for the task status. Originates from [`std::process::Child::wait`].
    #[error("could not wait for '{task}' to complete: {source}.")]
    CouldNotWait {
        /// The task that could not be waited for.
        task: String,

        /// The [`io::Error`] that was reported by [`std::process::Child::wait`].
        source: io::Error,
    },

    /// This error is returned when the current directory cannot be found. Originates from [`std::env::current_dir`].
    #[error("could not find current directory when initializing task: {source}.")]
    CouldNotFindCurrentDirectory {
        /// The [`io::Error`] that was reported by [`std::env::current_dir`].
        source: io::Error,
    },

    /// This error can be returned from log handlers to terminate early.
    #[error(transparent)]
    EarlyReturn(#[from] Box<dyn std::error::Error + Send + Sync + 'static>),

    /// This error is returned when the log lock is poisoned.
    #[error("encountered an unrecoverable error while processing logs for '{task}'.")]
    PoisonedLog {
        /// The task that encountered an unrecoverable error
        task: String,
    },
}