Skip to main content

pd_cipher::error

Error types and result handling for the PD.Cipher SDK. Error types and error handling for the PD.Cipher SDK.

This module defines [CipherError], the unified error type used throughout the SDK. All fallible operations return Result<T, CipherError>.

Error Categories

Errors are grouped into several categories:

  • Cryptographic Errors: Encryption/decryption failures, authentication issues
  • Key Errors: Invalid keys, algorithm mismatches
  • Data Errors: Invalid input, corrupted data, encoding issues
  • System Errors: I/O failures, RNG failures
  • Format Errors: Version mismatches, serialization issues

Error Handling Strategies

use pd_cipher::{PDCipher, CipherError, config::CipherConfig, KeyGenerator};

# #[tokio::main(flavor = "current_thread")]
# async fn main() -> pd_cipher::Result<()> {
let config = CipherConfig::default();

// 1. Use ? operator for propagation
let key = KeyGenerator::generate_key(config.algorithm)?;
let (encrypted, context) = PDCipher::encrypt(
&["data"],
&key,
&config
).await?;

// 2. Match on specific errors
let wrong_key = KeyGenerator::generate_key(config.algorithm)?;
let token_refs: Vec<&str> = encrypted.iter().map(|s| s.as_str()).collect();
match PDCipher::decrypt(&token_refs, &context, &wrong_key).await {
Ok(data) => println!("Decrypted: {:?}", data),
Err(CipherError::DecryptionFailed(_)) => {
println!("Authentication failed - check password");
}
Err(CipherError::Utf8Error(_)) => {
println!("Data is not valid UTF-8");
}
Err(e) => {
println!("Other error: {}", e);
}
}
# Ok(())
# }

Security Considerations

  • Never log sensitive data from errors
  • Avoid exposing internal error details to end users
  • Use constant-time operations when comparing authentication tags
  • Consider rate limiting after repeated authentication failures

Recovery Strategies

use pd_cipher::{PDCipher, CipherError, config::CipherConfig, KeyGenerator};
use std::time::Duration;
use std::thread;

# fn recover_from_errors() -> pd_cipher::Result<()> {
let config = CipherConfig::default();

// Retry with exponential backoff
fn retry_operation<F, T>(mut op: F) -> pd_cipher::Result<T>
where
F: FnMut() -> pd_cipher::Result<T>,
{
let mut retries = 0;
loop {
match op() {
Ok(result) => return Ok(result),
Err(CipherError::RngError(_)) if retries < 3 => {
// RNG might be temporarily exhausted
thread::sleep(Duration::from_millis(100 * 2_u64.pow(retries)));
retries += 1;
}
Err(e) => return Err(e),
}
}
}
# Ok(())
# }

Enums

CipherError

The main error type for all PD.Cipher SDK operations.

CipherError provides detailed error information while maintaining security. Error messages are designed to be helpful for debugging without revealing sensitive information about the encrypted data or keys.

Examples

Pattern Matching

use pd_cipher::{CipherError, PDCipher, EncryptionAlgorithm};

# fn handle_error(error: CipherError) {
match error {
CipherError::DecryptionFailed(_) => {
// Authentication failure - wrong password or corrupted data
eprintln!("Failed to decrypt - check your password");
}
CipherError::IncompatibleKey(_) => {
// Algorithm mismatch
eprintln!("Key type doesn't match encryption algorithm");
}
CipherError::IoError(io_err) => {
// Handle I/O errors
eprintln!("Storage error: {}", io_err);
}
_ => {
// Generic error handling
eprintln!("Operation failed: {}", error);
}
}
# }

Error Context

use pd_cipher::{PDCipher, CipherError, config::CipherConfig, KeyGenerator};

async fn process_user_data(data: &str) -> Result<String, String> {
let config = CipherConfig::default();

let key = KeyGenerator::generate_key(config.algorithm).map_err(|e| e.to_string())?;
PDCipher::encrypt(&[data], &key, &config).await
.map(|(tokens, _)| format!("Encrypted {} tokens", tokens.len()))
.map_err(|e| match e {
CipherError::ValidationError(msg) =>
format!("Invalid input data: {}", msg),
CipherError::RngError(_) =>
"System entropy exhausted - try again".to_string(),
_ => format!("Encryption failed: {}", e),
})
}
pub enum CipherError {
EncryptionFailed,
DecryptionFailed,
InvalidCiphertext,
InvalidPlaintext,
InvalidKey,
IncompatibleKey,
BincodeError,
ValidationError,
NumericObfuscationFailed,
IoError,
RngError,
KeyGenerationFailed,
UnsupportedVersion,
SerializationError,
DeserializationError,
Utf8Error,
ConfigurationError,
KeyProviderError,
LookupFailed,
}

Type Aliases

Result

A convenience type alias for Result<T, CipherError>.

All fallible operations in the SDK return this type.

Example

use pd_cipher::{Result, PDCipher, PDContext, config::CipherConfig, KeyGenerator};

async fn encrypt_data(data: &[&str]) -> Result<Vec<u8>> {
let config = CipherConfig::default();
let key = KeyGenerator::generate_key(config.algorithm)?;
let (_, context) = PDCipher::encrypt(data, &key, &config).await?;
context.to_bytes()
}
pub type Result<...> = ...