Skip to main content

Module errors

Module errors 

Source
Expand description

§Error handling for the age_crypto library

This module defines the unified error type and the alias Result used across the entire library. It re‑exports the sub‑module errors so that users can conveniently match on specific failure reasons if they wish.

§Structure

errors
├── decrypt.rs  → DecryptError (four variants for decrypt-specific failures)
├── encrypt.rs  → EncryptError (four variants for encrypt-specific failures)
└── mod.rs      → Error (top-level enum), Result type alias

The top‑level [Error] is an enum with two variants:

  • Error::Encrypt(EncryptError)
  • Error::Decrypt(DecryptError)

Both variants are created automatically from their respective sub‑errors thanks to the #[from] attribute. This means:

  1. Functions that work internally with DecryptError (e.g., the parse_identity helper) can return DecryptError without worrying about the outer type.
  2. The public API functions (e.g., crate::decrypt) have a return type of Result<T> (i.e., std::result::Result<T, Error>). When they use ? on an expression that returns Result<_, DecryptError>, the conversion to Error::Decrypt happens automatically.

§Usage for library consumers

§Basic error handling

use age_crypto::{decrypt_with_passphrase, Error};

// Contoh: ciphertext dummy untuk demonstrasi
let ciphertext = b"AGE-ENC..."; // hasil dari encrypt_with_passphrase
let passphrase = "my-secret-pass";

match decrypt_with_passphrase(ciphertext, passphrase) {
    Ok(plaintext) => println!("Decrypted: {:?}", std::str::from_utf8(&plaintext)),
    Err(Error::Decrypt(e)) => eprintln!("Decrypt error: {}", e),
    Err(Error::Encrypt(e)) => eprintln!("Unexpected encrypt error: {}", e),
}

§Distinguishing error kinds

use age_crypto::{decrypt_with_passphrase, Error};
use age_crypto::errors::DecryptError;

let ciphertext = b"invalid-ciphertext";
let passphrase = "wrong-pass";

match decrypt_with_passphrase(ciphertext, passphrase) {
    Ok(plain) => {
        // Handle successful decryption
        let _ = plain;
    }
    Err(Error::Decrypt(DecryptError::InvalidCiphertext(_))) => {
        // Handle corrupted or malformed ciphertext
        eprintln!("Ciphertext is invalid or corrupted");
    }
    Err(Error::Decrypt(DecryptError::Failed(_))) => {
        // Handle wrong passphrase or authentication failure
        eprintln!("Wrong passphrase or integrity check failed");
    }
    Err(Error::Decrypt(DecryptError::Io(e))) => {
        // Handle I/O errors during decryption
        eprintln!("I/O error: {}", e);
    }
    Err(other) => eprintln!("Unexpected error: {}", other),
}

§Why two‑level error design?

  • Separation of concerns: Encryption and decryption are distinct operations with different failure modes. Keeping them in separate enums makes the code self‑documenting.
  • Extensibility: In the future, we could add a ConfigError or KeyGenerationError variant to the top‑level Error without touching the encrypt/decrypt types.
  • Backward compatibility: Adding a new variant to a public enum is a breaking change. With the two‑level approach, we can sometimes add variants to DecryptError without directly breaking the top‑level Error ABI (though it still breaks exhaustive matches on DecryptError). The outer Error remains stable as long as we don’t add a new variant there.

Re-exports§

pub use decrypt::DecryptError;
pub use encrypt::EncryptError;

Modules§

decrypt
encrypt

Enums§

Error
The universal error type for this crate.

Type Aliases§

Result
Convenient alias for std::result::Result<T, crate::errors::Error>.