aven_core/sync/client/
errors.rs1use anyhow::Error;
6
7pub fn codes(error: &Error) -> impl Iterator<Item = String> + '_ {
9 error.chain().filter_map(|cause| {
10 cause
11 .to_string()
12 .strip_prefix("error ")
13 .and_then(|rest| rest.split_whitespace().next())
14 .map(str::to_string)
15 })
16}
17
18pub fn code(error: &Error) -> Option<String> {
20 codes(error).next()
21}
22
23pub fn has_code(error: &Error, expected: &str) -> bool {
24 codes(error).any(|code| code == expected)
25}
26
27pub fn is_stale(error: &Error) -> bool {
29 error.is::<crate::sync::seed_claim::membership::StaleContext>()
30}
31
32pub fn is_access_refusal(error: &Error) -> bool {
35 has_code(error, "sync-server-refused")
36 || has_code(error, "enrollment-unauthorized")
37 || has_code(error, "enrollment-revoked")
38 || has_code(error, "sync-device-removed")
39}
40
41pub fn is_vault_deleted(error: &Error) -> bool {
44 has_code(error, VAULT_DELETED)
45}
46
47const VAULT_DELETED: &str = "sync-vault-deleted";
48
49pub(crate) fn hosting_error(hosting: aven_protocol::refusal::Hosting) -> Error {
51 use aven_protocol::refusal::Hosting;
52 let code = match hosting {
53 Hosting::Blocked => "sync-hosting-blocked",
54 Hosting::Deleted => VAULT_DELETED,
55 Hosting::Quota => "sync-hosting-quota",
56 Hosting::Unavailable => "sync-hosting-unavailable",
57 };
58 anyhow::anyhow!("error {code} outcome-unknown")
59}
60
61pub(crate) fn is_hosting_refusal(error: &Error) -> bool {
62 codes(error).any(|code| {
63 matches!(
64 code.as_str(),
65 "sync-hosting-blocked"
66 | "sync-hosting-quota"
67 | "sync-hosting-unavailable"
68 | VAULT_DELETED
69 )
70 })
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76 use aven_protocol::refusal::Hosting;
77
78 #[test]
79 fn every_hosting_refusal_stops_transfers_and_only_deletion_is_terminal() {
80 for hosting in [
81 Hosting::Blocked,
82 Hosting::Deleted,
83 Hosting::Quota,
84 Hosting::Unavailable,
85 ] {
86 let error = hosting_error(hosting).context("error sync-round");
87 assert!(is_hosting_refusal(&error));
88 assert!(!is_access_refusal(&error));
89 assert_eq!(is_vault_deleted(&error), hosting == Hosting::Deleted);
90 }
91 }
92}