Skip to main content

nextcloud_goa/
error.rs

1//! Error types for GNOME Online Accounts integration.
2
3use std::error::Error;
4use std::fmt;
5
6use nextcloud_sdk_core::UrlError;
7
8/// Errors that can occur when discovering GNOME Online Accounts.
9#[derive(Debug)]
10pub enum GoaError {
11    /// A D-Bus communication error.
12    DBus(zbus::Error),
13    /// A URL parsing error while determining the server base URL.
14    Url(UrlError),
15    /// No Nextcloud or ownCloud accounts were configured in GNOME Online Accounts.
16    NoAccountsFound,
17    /// A required D-Bus property was missing or not of expected type.
18    MissingProperty(&'static str),
19}
20
21impl fmt::Display for GoaError {
22    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23        match self {
24            Self::DBus(err) => write!(f, "D-Bus operation failed: {err}"),
25            Self::Url(err) => write!(f, "failed to parse server URL: {err}"),
26            Self::NoAccountsFound => {
27                f.write_str("no Nextcloud or ownCloud accounts found in GNOME Online Accounts")
28            }
29            Self::MissingProperty(prop) => {
30                write!(f, "missing required D-Bus property `{prop}`")
31            }
32        }
33    }
34}
35
36impl Error for GoaError {
37    fn source(&self) -> Option<&(dyn Error + 'static)> {
38        match self {
39            Self::DBus(err) => Some(err),
40            Self::Url(err) => Some(err),
41            Self::NoAccountsFound | Self::MissingProperty(_) => None,
42        }
43    }
44}
45
46impl From<zbus::Error> for GoaError {
47    fn from(err: zbus::Error) -> Self {
48        Self::DBus(err)
49    }
50}
51
52impl From<UrlError> for GoaError {
53    fn from(err: UrlError) -> Self {
54        Self::Url(err)
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use std::error::Error;
61
62    use nextcloud_sdk_core::UrlError;
63
64    use super::GoaError;
65
66    #[test]
67    fn display_formats_all_variants() {
68        assert!(
69            GoaError::NoAccountsFound
70                .to_string()
71                .contains("no Nextcloud")
72        );
73        assert!(
74            GoaError::MissingProperty("Id")
75                .to_string()
76                .contains("missing required D-Bus property `Id`")
77        );
78        assert!(
79            GoaError::Url(UrlError::MissingScheme)
80                .to_string()
81                .contains("server URL has no scheme")
82        );
83    }
84
85    #[test]
86    fn source_returns_underlying_error() {
87        let url_err = GoaError::Url(UrlError::MissingScheme);
88        assert!(url_err.source().is_some());
89
90        let missing = GoaError::MissingProperty("Id");
91        assert!(missing.source().is_none());
92
93        let no_acc = GoaError::NoAccountsFound;
94        assert!(no_acc.source().is_none());
95    }
96}