feat(gui): error helper to classify zbus errors and produce user messages
This commit is contained in:
87
gui/src/error.rs
Normal file
87
gui/src/error.rs
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
//! Map zbus errors to short, user-facing strings. The GUI surfaces these in
|
||||||
|
//! `adw::Toast` and inside the touch-prompt dialog's failure state.
|
||||||
|
//!
|
||||||
|
//! Pure logic; testable without a display server.
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
#[allow(dead_code)] // wired through keys_page.rs / enroll_dialog.rs in Tasks 4-6.
|
||||||
|
pub(crate) enum ErrorKind {
|
||||||
|
/// Daemon unreachable / bus dropped — caller should swap to disconnected banner.
|
||||||
|
Disconnected,
|
||||||
|
/// polkit denied. Daemon's message is usually fine to show verbatim.
|
||||||
|
AccessDenied,
|
||||||
|
/// Anything else — daemon returned a typed `Failed(msg)` or similar.
|
||||||
|
Other,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)] // wired through keys_page.rs / enroll_dialog.rs in Tasks 4-6.
|
||||||
|
pub(crate) fn classify(err: &zbus::Error) -> ErrorKind {
|
||||||
|
match err {
|
||||||
|
zbus::Error::InputOutput(_) | zbus::Error::Address(_) | zbus::Error::Handshake(_) => {
|
||||||
|
ErrorKind::Disconnected
|
||||||
|
}
|
||||||
|
zbus::Error::FDO(boxed) => match boxed.as_ref() {
|
||||||
|
zbus::fdo::Error::AccessDenied(_) => ErrorKind::AccessDenied,
|
||||||
|
zbus::fdo::Error::ServiceUnknown(_) | zbus::fdo::Error::NameHasNoOwner(_) => {
|
||||||
|
ErrorKind::Disconnected
|
||||||
|
}
|
||||||
|
_ => ErrorKind::Other,
|
||||||
|
},
|
||||||
|
_ => ErrorKind::Other,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)] // wired through keys_page.rs / enroll_dialog.rs in Tasks 4-6.
|
||||||
|
pub(crate) fn user_message(err: &zbus::Error) -> String {
|
||||||
|
match classify(err) {
|
||||||
|
ErrorKind::Disconnected => {
|
||||||
|
"Couldn't reach the authentication daemon. Make sure authforge-daemon is running."
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
ErrorKind::AccessDenied => match err {
|
||||||
|
zbus::Error::FDO(boxed) => match boxed.as_ref() {
|
||||||
|
zbus::fdo::Error::AccessDenied(msg) => msg.clone(),
|
||||||
|
_ => "Access denied.".to_string(),
|
||||||
|
},
|
||||||
|
_ => "Access denied.".to_string(),
|
||||||
|
},
|
||||||
|
ErrorKind::Other => err.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn service_unknown_classifies_as_disconnected() {
|
||||||
|
let e = zbus::Error::FDO(Box::new(zbus::fdo::Error::ServiceUnknown(
|
||||||
|
"no daemon".to_string(),
|
||||||
|
)));
|
||||||
|
assert_eq!(classify(&e), ErrorKind::Disconnected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn access_denied_classifies_as_access_denied() {
|
||||||
|
let e = zbus::Error::FDO(Box::new(zbus::fdo::Error::AccessDenied(
|
||||||
|
"polkit said no".to_string(),
|
||||||
|
)));
|
||||||
|
assert_eq!(classify(&e), ErrorKind::AccessDenied);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn access_denied_user_message_is_daemon_message_verbatim() {
|
||||||
|
let e = zbus::Error::FDO(Box::new(zbus::fdo::Error::AccessDenied(
|
||||||
|
"polkit said no".to_string(),
|
||||||
|
)));
|
||||||
|
assert_eq!(user_message(&e), "polkit said no");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn disconnected_user_message_mentions_authforge_daemon() {
|
||||||
|
let e = zbus::Error::FDO(Box::new(zbus::fdo::Error::ServiceUnknown(
|
||||||
|
"no daemon".to_string(),
|
||||||
|
)));
|
||||||
|
assert!(user_message(&e).contains("authforge-daemon"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
|
|
||||||
|
mod error;
|
||||||
|
|
||||||
const APP_ID: &str = "io.dangerousthings.AuthForge";
|
const APP_ID: &str = "io.dangerousthings.AuthForge";
|
||||||
|
|
||||||
fn main() -> glib::ExitCode {
|
fn main() -> glib::ExitCode {
|
||||||
|
|||||||
Reference in New Issue
Block a user