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