pub enum EncryptError {
NoRecipients,
InvalidRecipient {
recipient: String,
reason: String,
},
Failed(String),
Io(Error),
}Expand description
Errors that can happen during encryption operations.
§Overview
EncryptError enumerates every failure path specific to encryption:
invalid recipient keys, missing recipients, internal encryption
failures, and I/O glitches. It is the symmetric counterpart to
[DecryptError] and follows the same design principles:
- Fine‑grained – callers can distinguish between “no recipients” and “invalid recipient X” and act accordingly (e.g., ask the user to provide a correct key).
- Context‑rich – the error variants carry the problematic data
(
recipientfield) and areasonstring, so error messages are self‑contained and helpful. - Ergonomic – automatic
Fromconversions mean minimal boilerplate inside the encryption functions.
All public encryption APIs return crate::errors::Result<T>, where
crate::errors::Error can hold an EncryptError via the #[from]
conversion.
§Example: Basic error handling with public API
use age_crypto::{encrypt_with_passphrase, Error};
let plaintext = b"Secret message";
let passphrase = "my-strong-passphrase";
match encrypt_with_passphrase(plaintext, passphrase) {
Ok(encrypted) => {
println!("Encrypted {} bytes", encrypted.as_bytes().len());
}
Err(Error::Encrypt(e)) => {
eprintln!("Encryption error: {}", e);
}
Err(e) => {
eprintln!("Unexpected error: {}", e);
}
}§Example: Distinguishing specific error variants
use age_crypto::{encrypt_with_passphrase, Error};
use age_crypto::errors::EncryptError;
// Contoh: mencoba encrypt dengan passphrase kosong (mungkin gagal tergantung implementasi)
let result = encrypt_with_passphrase(b"test", "");
if let Err(Error::Encrypt(err)) = result {
match err {
EncryptError::NoRecipients => {
// Variant ini lebih relevan untuk key-based encryption
eprintln!("No recipients specified");
}
EncryptError::InvalidRecipient { recipient, reason } => {
eprintln!("Recipient '{}' is invalid: {}", recipient, reason);
}
EncryptError::Failed(msg) => {
eprintln!("Encryption failed internally: {}", msg);
}
EncryptError::Io(e) => {
eprintln!("I/O error during encryption: {}", e);
}
}
}§Error handling philosophy
- No panics – all error paths return a
Result; the library never aborts due to invalid input. - Transparent wrapping – underlying library errors (from the
agecrate) are stringified with.to_string()so that the error chain remains meaningful even if the inner error type is not exposed. - I/O errors are propagated automatically – see [
Io] variant.
Variants§
NoRecipients
The list of recipients is empty.
Age encryption requires at least one valid public key so that the
resulting ciphertext can be decrypted by the corresponding private
key. This error is returned immediately from the
parse_recipients helper when an empty slice is provided, before
any cryptographic work is done.
Why not just encrypt to “no one”?
That would produce a ciphertext that cannot be decrypted, which is
almost certainly a mistake. By treating this as an error, we force
the caller to consciously provide a recipient.
§Example scenario
use age_crypto::errors::EncryptError;
fn validate_recipients(recips: &[String]) -> Result<(), EncryptError> {
if recips.is_empty() {
return Err(EncryptError::NoRecipients);
}
Ok(())
}
// Usage:
assert!(validate_recipients(&[]).is_err());
assert!(validate_recipients(&["age1valid...".into()]).is_ok());InvalidRecipient
A specific recipient string could not be parsed as a valid X25519 public key.
Age public keys normally look like age1... followed by a Bech32
string. This variant is returned when x25519::Recipient::from_str
fails. The fields are:
recipient: the original string that failed to parse.reason: the parser’s error description (e.g., “invalid bech32”, “bad checksum”, “unsupported version”).
By including the offending string, the caller can report exactly which recipient was problematic without needing to copy it into the error themselves.
§Example: Parsing validation
use std::str::FromStr;
use age::x25519::Recipient;
use age_crypto::errors::EncryptError;
let key = "age1-invalid-key-format";
// Attempt to parse; on failure, convert to our error type
Recipient::from_str(key)
.map_err(|e| EncryptError::InvalidRecipient {
recipient: key.to_string(),
reason: format!("Parse error: {}", e),
})?;§Example: Error output format
recipients = ["age1valid", "not-a-key", "age1another"]
-> EncryptError::InvalidRecipient {
recipient: "not-a-key",
reason: "invalid bech32 checksum"
}
-> Display: "Invalid recipient 'not-a-key': invalid bech32 checksum"Fields
Failed(String)
The encryption process encountered an internal error.
This variant covers all age‑internal failures that are not related to recipient parsing or I/O. For example:
- Failure to generate a shared secret from a recipient’s key.
- Failure to wrap the symmetric key.
- Unexpected errors from the random number generator.
The inner String contains whatever error message the age
crate produced. While this is not as structured as the other
variants, it ensures no error is silently swallowed.
§When this occurs
This error is relatively rare in practice because the age crate
is well-tested. Common triggers include:
- Memory allocation failures during cryptographic operations
- Unexpected state in the encryption state machine
- Platform-specific cryptographic backend issues
§Debugging tip
If you encounter this error frequently, consider:
- Updating the
ageandage-cryptocrates to latest versions - Checking system resources (memory, entropy pool)
- Reporting the issue with the full error message for investigation
Io(Error)
An I/O error occurred while writing the encrypted output.
Even though our API writes into a Vec<u8>, the Encryptor uses
a generic Write implementation. In extremely rare circumstances
(e.g., out‑of‑memory), writing to the vector may yield an
io::Error.
Because this variant is annotated with #[from] io::Error, any
? on an I/O operation inside an encryption function will
automatically promote the io::Error into EncryptError::Io.
§Example of automatic I/O error conversion
use std::io::Write;
use age_crypto::errors::EncryptError;
fn write_encrypted<W: Write>(
writer: &mut W,
plaintext: &[u8]
) -> Result<(), EncryptError> {
// Any io::Error from write_all is automatically converted
// to EncryptError::Io via the `?` operator
writer.write_all(plaintext)?;
Ok(())
}§Common I/O error scenarios
| ErrorKind | Likely cause |
|---|---|
WriteZero | Writer returned 0 bytes written (unusual for Vec) |
OutOfMemory | System ran out of memory during allocation |
Interrupted | Operation interrupted by signal (rare in memory ops) |
Implementations§
Source§impl EncryptError
impl EncryptError
Sourcepub fn is_user_correctable(&self) -> bool
pub fn is_user_correctable(&self) -> bool
Returns true if this error indicates a user-correctable issue
(e.g., invalid recipient format) rather than an internal failure.
This can help decide whether to prompt the user to retry with different input.
§Example
use age_crypto::errors::EncryptError;
let err = EncryptError::InvalidRecipient {
recipient: "bad-key".into(),
reason: "invalid bech32".into(),
};
if err.is_user_correctable() {
println!("Please check your recipient key and try again.");
}Sourcepub fn invalid_recipient(&self) -> Option<&str>
pub fn invalid_recipient(&self) -> Option<&str>
Returns the problematic recipient string if this is an
InvalidRecipient error, or None otherwise.
§Example
use age_crypto::errors::EncryptError;
let err = EncryptError::InvalidRecipient {
recipient: "age1bad...".into(),
reason: "checksum failed".into(),
};
if let Some(bad_key) = err.invalid_recipient() {
eprintln!("The key '{}' is invalid", bad_key);
}Trait Implementations§
Source§impl Debug for EncryptError
impl Debug for EncryptError
Source§impl Display for EncryptError
impl Display for EncryptError
Source§impl Error for EncryptError
impl Error for EncryptError
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()