urma_node/install/
error.rs1use 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}