Skip to main content

tsafe_core/
errors.rs

1//! Error types for tsafe-core.
2//!
3//! All fallible public functions return [`SafeResult<T>`], which is an alias for
4//! `Result<T, SafeError>`.  Callers can match on specific variants for structured
5//! error handling or surface the `Display` message (derived by `thiserror`) for
6//! user-facing output.
7
8use thiserror::Error;
9
10/// Top-level error type for all tsafe-core operations.
11#[derive(Debug, Error)]
12pub enum SafeError {
13    #[error("vault not found: {path}")]
14    VaultNotFound { path: String },
15
16    #[error("vault already exists: {path}")]
17    VaultAlreadyExists { path: String },
18
19    #[error("secret not found: {key}")]
20    SecretNotFound { key: String },
21
22    #[error("secret already exists: {key}")]
23    SecretAlreadyExists { key: String },
24
25    #[error("profile not found: {name}")]
26    ProfileNotFound { name: String },
27
28    #[error("decryption failed — wrong password or corrupted vault")]
29    DecryptionFailed,
30
31    #[error("crypto error: {context}")]
32    Crypto { context: String },
33
34    #[error("invalid vault: {reason}")]
35    InvalidVault { reason: String },
36
37    #[error("import parse error in {file}: {reason}")]
38    ImportParse { file: String, reason: String },
39
40    #[error("no snapshots available to restore profile '{profile}'")]
41    NoSnapshotAvailable { profile: String },
42
43    #[error("snapshot not found: {path}")]
44    SnapshotNotFound { path: String },
45
46    #[error("vault schema migration failed: {reason}")]
47    MigrationFailed { reason: String },
48
49    #[error("vault is corrupted and could not be auto-healed: {reason}")]
50    VaultCorrupted { reason: String },
51
52    /// The OS credential store entry for biometric/keyring unlock is stale.
53    ///
54    /// This occurs when the vault password was rotated, a new fingerprint enrolled,
55    /// or the biometric enrollment changed after `tsafe biometric enable` was run.
56    /// The stored credential no longer matches — the user must re-enroll explicitly.
57    ///
58    /// Callers MUST NOT silently fall through to another method. Surface this
59    /// error with a clear message directing the user to `tsafe biometric re-enroll`.
60    #[error(
61        "stale biometric credential: the stored credential no longer matches the vault (password \
62         was rotated or biometric enrollment changed). Run `tsafe biometric re-enroll` to \
63         restore password-free unlock."
64    )]
65    StaleBiometricCredential,
66
67    /// The Windows Hello verification dialog was dismissed by the user before
68    /// completing. The vault unlock is not permitted; the caller must not fall
69    /// through to another unlock method.
70    #[error("Windows Hello verification was canceled by the user")]
71    BiometricCanceled,
72
73    /// A Windows Hello verification attempt failed for a reason other than
74    /// user cancellation (device not ready, OS error, etc.).
75    #[error("Windows Hello verification failed: {0}")]
76    BiometricFailed(String),
77
78    #[error("io error: {0}")]
79    Io(#[from] std::io::Error),
80
81    #[error("serialization error: {0}")]
82    Serialization(#[from] serde_json::Error),
83}
84
85/// Convenience alias for `Result<T, SafeError>`.
86pub type SafeResult<T> = Result<T, SafeError>;