passless_core/
error.rs

1//! Error types for Passless
2//!
3//! This module defines all error types used in the Passless authenticator.
4//! We use `thiserror` for structured error handling with proper error context.
5
6use std::io;
7
8use thiserror::Error;
9
10/// Result type alias using PasslessError
11pub type Result<T> = std::result::Result<T, Error>;
12
13/// Passless-specific errors
14///
15/// These errors represent domain and infrastructure failures.
16/// They can be converted to keylib::Error when needed for compatibility.
17#[derive(Error, Debug)]
18pub enum Error {
19    /// Storage-related errors
20    #[error("Storage error: {0}")]
21    Storage(String),
22
23    /// Configuration errors
24    #[error("Configuration error: {0}")]
25    Config(String),
26
27    /// UHID device errors
28    #[error("UHID error: {0}")]
29    Uhid(String),
30
31    /// Credential management errors
32    #[error("Credential management error: {0}")]
33    CredentialManagement(String),
34
35    /// User verification failed
36    #[error("User verification failed: {0}")]
37    UserVerificationFailed(String),
38
39    /// Operation cancelled by user
40    #[error("Operation cancelled by user")]
41    Cancelled,
42
43    /// Generic IO error
44    #[error("IO error: {0}")]
45    Io(#[from] io::Error),
46
47    /// Serialization/deserialization error
48    #[error("Serialization error: {0}")]
49    Serialization(String),
50
51    /// Invalid data format
52    #[error("Invalid data: {0}")]
53    InvalidData(String),
54
55    /// Generic other error
56    #[error("Other error: {0}")]
57    Other(String),
58}
59
60/// Convert soft_fido2::Error to Error for error handling
61impl From<soft_fido2::Error> for Error {
62    fn from(err: soft_fido2::Error) -> Self {
63        Error::CredentialManagement(format!("{:?}", err))
64    }
65}
66
67/// Convert Error to soft_fido2::Error for compatibility
68impl From<Error> for soft_fido2::Error {
69    fn from(err: Error) -> Self {
70        match err {
71            Error::Storage(ref msg) if msg.contains("not found") => soft_fido2::Error::DoesNotExist,
72            Error::Storage(ref msg) if msg.contains("No more credentials") => {
73                soft_fido2::Error::DoesNotExist
74            }
75            _ => soft_fido2::Error::Other,
76        }
77    }
78}
79
80#[cfg(test)]
81mod tests {
82    use super::*;
83
84    #[test]
85    fn test_soft_fido2_error_conversion() {
86        let err: Error = soft_fido2::Error::DoesNotExist.into();
87        assert!(matches!(err, Error::CredentialManagement(_)));
88
89        let err: soft_fido2::Error = Error::Storage("not found".to_string()).into();
90        assert!(matches!(err, soft_fido2::Error::DoesNotExist));
91    }
92}