baseid_wallet_core/
error.rs1use baseid_core::error::ProtocolError;
4use baseid_core::language::Language;
5use baseid_core::types::CredentialId;
6
7#[derive(Debug, thiserror::Error)]
9pub enum WalletError {
10 #[error("credential not found: {0:?}")]
11 CredentialNotFound(CredentialId),
12 #[error("unsupported credential format: {0}")]
13 UnsupportedFormat(String),
14 #[error("credential parse error: {0}")]
15 CredentialParseError(String),
16 #[error("credential matching failed: {0}")]
17 MatchingFailed(String),
18 #[error("presentation failed: {0}")]
19 PresentationFailed(String),
20 #[error("storage error: {0}")]
21 StorageError(String),
22}
23
24impl baseid_core::error::BilingualError for WalletError {
25 fn message(&self, lang: Language) -> &str {
26 match (self, lang) {
27 (WalletError::CredentialNotFound(_), Language::Fr) => "attestation introuvable",
28 (WalletError::CredentialNotFound(_), _) => "credential not found",
29 (WalletError::UnsupportedFormat(_), Language::Fr) => {
30 "format d'attestation non pris en charge"
31 }
32 (WalletError::UnsupportedFormat(_), _) => "unsupported credential format",
33 (WalletError::CredentialParseError(_), Language::Fr) => {
34 "erreur d'analyse de l'attestation"
35 }
36 (WalletError::CredentialParseError(_), _) => "credential parse error",
37 (WalletError::MatchingFailed(_), Language::Fr) => {
38 "échec de la correspondance des attestations"
39 }
40 (WalletError::MatchingFailed(_), _) => "credential matching failed",
41 (WalletError::PresentationFailed(_), Language::Fr) => "échec de la présentation",
42 (WalletError::PresentationFailed(_), _) => "presentation failed",
43 (WalletError::StorageError(_), Language::Fr) => "erreur de stockage",
44 (WalletError::StorageError(_), _) => "storage error",
45 }
46 }
47}
48
49impl From<WalletError> for baseid_core::Error {
50 fn from(e: WalletError) -> Self {
51 match &e {
52 WalletError::CredentialNotFound(_) => ProtocolError::General.into(),
53 WalletError::UnsupportedFormat(_) => ProtocolError::General.into(),
54 WalletError::CredentialParseError(_) => ProtocolError::InvalidResponse.into(),
55 WalletError::MatchingFailed(_) => ProtocolError::General.into(),
56 WalletError::PresentationFailed(_) => ProtocolError::General.into(),
57 WalletError::StorageError(_) => ProtocolError::Transport.into(),
58 }
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn error_display_all_variants() {
68 let variants: Vec<WalletError> = vec![
69 WalletError::CredentialNotFound(CredentialId("id-1".into())),
70 WalletError::UnsupportedFormat("unknown".into()),
71 WalletError::CredentialParseError("bad json".into()),
72 WalletError::MatchingFailed("no match".into()),
73 WalletError::PresentationFailed("signing failed".into()),
74 WalletError::StorageError("disk full".into()),
75 ];
76 for v in &variants {
77 assert!(!v.to_string().is_empty());
78 }
79 }
80
81 #[test]
82 fn bilingual_error_en_fr() {
83 use baseid_core::error::BilingualError;
84 let e = WalletError::CredentialNotFound(CredentialId("x".into()));
85 assert_eq!(e.message(Language::En), "credential not found");
86 assert_eq!(e.message(Language::Fr), "attestation introuvable");
87 }
88
89 #[test]
90 fn error_conversion_all_variants() {
91 let variants: Vec<WalletError> = vec![
92 WalletError::CredentialNotFound(CredentialId("a".into())),
93 WalletError::UnsupportedFormat("b".into()),
94 WalletError::CredentialParseError("c".into()),
95 WalletError::MatchingFailed("d".into()),
96 WalletError::PresentationFailed("e".into()),
97 WalletError::StorageError("f".into()),
98 ];
99 for v in variants {
100 let core_err: baseid_core::Error = v.into();
101 assert!(!format!("{core_err}").is_empty());
102 }
103 }
104}