#[non_exhaustive]
#[derive(Debug, thiserror::Error)]
pub enum WebauthnError {
#[error("Configuration error: {0}")]
Config(String),
#[error("Invalid challenge: {0}")]
InvalidChallenge(String),
#[error("Credential not found: {0}")]
CredentialNotFound(String),
#[error("Verification failed: {0}")]
VerificationFailed(String),
#[error("Duplicate credential: {0}")]
DuplicateCredential(String),
#[error("User not found: {0}")]
UserNotFound(String),
#[error("Challenge expired")]
ChallengeExpired,
#[error("Unsupported algorithm: {0}")]
UnsupportedAlgorithm(i32),
#[error("Signature verification failed")]
SignatureVerificationFailed,
#[error("Attestation error: {0}")]
AttestationError(String),
#[error("User verification required but not performed")]
UserVerificationRequired,
#[error("Credential policy violation: {0}")]
PolicyViolation(String),
}
#[allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::indexing_slicing,
clippy::panic
)]
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_display_variants() {
let errors = vec![
WebauthnError::Config("test".to_string()),
WebauthnError::InvalidChallenge("test".to_string()),
WebauthnError::CredentialNotFound("test".to_string()),
WebauthnError::VerificationFailed("test".to_string()),
WebauthnError::DuplicateCredential("test".to_string()),
WebauthnError::UserNotFound("test".to_string()),
WebauthnError::ChallengeExpired,
WebauthnError::UnsupportedAlgorithm(-7),
WebauthnError::SignatureVerificationFailed,
WebauthnError::AttestationError("test".to_string()),
WebauthnError::UserVerificationRequired,
WebauthnError::PolicyViolation("test".to_string()),
];
for err in errors {
assert!(!format!("{err}").is_empty());
assert!(!format!("{err:?}").is_empty());
}
}
}