1use serde::{Deserialize, Serialize};
7use thiserror::Error;
8
9#[derive(Debug, Clone, Error, Serialize, Deserialize)]
15pub enum GuiError {
16 #[error("Authentication failed: {reason}")]
18 AuthFailed { reason: String },
19
20 #[error("Network unreachable: {details}")]
22 NetworkUnreachable { details: String },
23
24 #[error("Configuration invalid: {field} - {reason}")]
26 ConfigInvalid { field: String, reason: String },
27
28 #[error("Connection closed: {reason}")]
30 ConnectionClosed { reason: String },
31
32 #[error("IPC error: {0}")]
34 Ipc(String),
35
36 #[error("Daemon error: {0}")]
38 Daemon(String),
39
40 #[error("Timeout: {0}")]
42 Timeout(String),
43
44 #[error("Permission denied: {0}")]
46 PermissionDenied(String),
47
48 #[error("{0}")]
50 Other(String),
51}
52
53impl GuiError {
54 pub fn auth_failed(reason: impl Into<String>) -> Self {
56 Self::AuthFailed {
57 reason: reason.into(),
58 }
59 }
60
61 pub fn network_unreachable(details: impl Into<String>) -> Self {
63 Self::NetworkUnreachable {
64 details: details.into(),
65 }
66 }
67
68 pub fn config_invalid(field: impl Into<String>, reason: impl Into<String>) -> Self {
70 Self::ConfigInvalid {
71 field: field.into(),
72 reason: reason.into(),
73 }
74 }
75
76 pub fn connection_closed(reason: impl Into<String>) -> Self {
78 Self::ConnectionClosed {
79 reason: reason.into(),
80 }
81 }
82
83 pub fn ipc(msg: impl Into<String>) -> Self {
85 Self::Ipc(msg.into())
86 }
87
88 pub fn daemon(msg: impl Into<String>) -> Self {
90 Self::Daemon(msg.into())
91 }
92
93 pub fn timeout(msg: impl Into<String>) -> Self {
95 Self::Timeout(msg.into())
96 }
97
98 pub fn permission_denied(msg: impl Into<String>) -> Self {
100 Self::PermissionDenied(msg.into())
101 }
102
103 pub fn other(msg: impl Into<String>) -> Self {
105 Self::Other(msg.into())
106 }
107}
108
109impl From<std::io::Error> for GuiError {
111 fn from(err: std::io::Error) -> Self {
112 match err.kind() {
113 std::io::ErrorKind::PermissionDenied => Self::permission_denied(err.to_string()),
114 std::io::ErrorKind::TimedOut => Self::timeout(err.to_string()),
115 std::io::ErrorKind::ConnectionRefused
116 | std::io::ErrorKind::ConnectionReset
117 | std::io::ErrorKind::ConnectionAborted => Self::connection_closed(err.to_string()),
118 _ => Self::other(err.to_string()),
119 }
120 }
121}
122
123impl From<quincy::QuincyError> for GuiError {
128 fn from(err: quincy::QuincyError) -> Self {
129 Self::Other(err.to_string())
132 }
133}
134
135impl From<serde_json::Error> for GuiError {
137 fn from(err: serde_json::Error) -> Self {
138 Self::Other(format!("JSON error: {}", err))
139 }
140}