Skip to main content

urma_node/install/
error.rs

1use crate::{Error as NodeError, platform::Paths};
2use std::{fmt, io, path::Path};
3
4#[derive(Debug)]
5pub enum Error {
6    NoInit,
7    Failed(String),
8    Io(io::Error),
9    Json(serde_json::Error),
10    Command {
11        program: String,
12        args: Vec<String>,
13        detail: String,
14    },
15    NotInstalled,
16    Account(String),
17    Node(NodeError),
18    #[cfg(windows)]
19    Windows {
20        call: &'static str,
21        error: windows_service::Error,
22    },
23}
24
25impl Error {
26    fn no_init(f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
27        let paths = Paths::linux_under(Path::new("/"));
28        write!(
29            f,
30            "No supported init system found (systemd, OpenRC, runit). Configure your service \
31             manager to run `urma-node service run` as user urma-node.\n  \
32             binaries: /usr/bin/urma-node, /usr/bin/urma-node-control, /usr/bin/urma-node-app\n  \
33             service settings: {}\n  archive config: {}\n  data: {}\n  \
34             token: {} (0640, urma-node:urma-node)\n  peer key: {} (0600)",
35            paths.settings.display(),
36            paths.config.display(),
37            paths.data.display(),
38            paths.token.display(),
39            paths.peer_key.display(),
40        )
41    }
42}
43
44impl fmt::Display for Error {
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
46        match self {
47            Self::NoInit => Self::no_init(f),
48            Self::Failed(message) => f.write_str(message),
49            Self::Io(error) => write!(f, "service I/O: {error}"),
50            Self::Json(error) => write!(f, "service status encoding: {error}"),
51            Self::Command {
52                program,
53                args,
54                detail,
55            } => write!(f, "`{program} {}` failed: {detail}", args.join(" ")),
56            Self::NotInstalled => {
57                f.write_str("the service is not installed; run `urma-node service install`")
58            }
59            Self::Account(message) => write!(f, "service account: {message}"),
60            Self::Node(error) => write!(f, "service defaults: {error}"),
61            #[cfg(windows)]
62            Self::Windows { call, error } => match error {
63                windows_service::Error::Winapi(cause) => {
64                    write!(f, "Windows service manager: {call}: {cause}")
65                }
66                other => write!(f, "Windows service manager: {call}: {other}"),
67            },
68        }
69    }
70}
71
72impl std::error::Error for Error {
73    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
74        match self {
75            Self::Io(error) => Some(error),
76            Self::Json(error) => Some(error),
77            Self::Node(error) => Some(error),
78            #[cfg(windows)]
79            Self::Windows { error, .. } => Some(error),
80            _ => None,
81        }
82    }
83}
84
85impl From<io::Error> for Error {
86    fn from(error: io::Error) -> Self {
87        Self::Io(error)
88    }
89}
90
91impl From<serde_json::Error> for Error {
92    fn from(error: serde_json::Error) -> Self {
93        Self::Json(error)
94    }
95}
96
97impl From<NodeError> for Error {
98    fn from(error: NodeError) -> Self {
99        Self::Node(error)
100    }
101}