fallibles

Crates.iofallibles
lib.rsfallibles
version0.1.3
created_at2026-01-13 09:16:02.298445+00
updated_at2026-01-13 12:49:10.695602+00
descriptionFailure injection library for testing error handling in Rust
homepage
repositoryhttps://github.com/s0uthview/fallibles
max_upload_size
id2039763
size16,588
Saoirse (s0uthview)

documentation

README

fallibles

Fallibles enables controlled failure injection for testing error handling in Rust applications. Mark functions with #[fallible] and configure when they should fail for comprehensive testing.

Features

  • fallibles-sim - Enable failure injection (required)
  • std - Standard library support (default)
  • anyhow - Support for anyhow::Error
  • eyre - Support for eyre::Report

Quick Start

use fallibles::*;

#[fallible]
fn database_query() -> Result<String, &'static str> {
    Ok("data".to_string())
}

// Enable 30% failure rate
fallibles_core::configure_failures(
    fallibles_core::FailureConfig::new().with_probability(0.3)
);

Examples

Basic Usage

use fallibles::*;

#[fallible]
fn read_config() -> Result<i32, &'static str> {
    Ok(42)
}

// Without config, function always succeeds
assert_eq!(read_config().unwrap(), 42);

// Enable failures with RAII guard
{
    let _guard = fallibles_core::with_config(
        fallibles_core::FailureConfig::new().with_probability(1.0)
    );
    // Now it will fail
    assert!(read_config().is_err());
} // Config automatically cleared

Inline Configuration

use fallibles::*;

#[fallible(probability = 0.2)]  // 20% failure rate
fn flaky_api() -> Result<String, &'static str> {
    Ok("response".to_string())
}

#[fallible(trigger_every = 5)]  // Fail every 5th call
fn periodic_task() -> Result<(), String> {
    Ok(())
}

Policy-Based Testing

use fallibles::fallibles_core::{FailureConfig, with_config};

// Chaos Monkey: 10% random failures
let _guard = with_config(FailureConfig::chaos_monkey());

// Degraded Service: 30% failures
let _guard = with_config(FailureConfig::degraded_service(0.3));

// Circuit Breaker: fail every 5th call
let _guard = with_config(FailureConfig::circuit_breaker(5));

Conditional Failures

use fallibles::fallibles_core::{FailureConfig, with_config};

// Only fail when environment variable is set
let _guard = with_config(
    FailureConfig::new()
        .with_probability(0.5)
        .when(|| std::env::var("CHAOS_MODE").is_ok())
);

Reproducible Testing

use fallibles::fallibles_core::{FailureConfig, with_config};

// Same seed always produces same failure pattern
let _guard = with_config(
    FailureConfig::new()
        .with_probability(0.3)
        .with_seed(12345)
);
// Or from environment: FALLIBLES_SEED=12345 cargo test

Custom Error Types

use fallibles::*;

#[derive(Debug, FallibleError)]
#[fallible(message = "timeout occurred")]
struct TimeoutError {
    message: String,
}

#[fallible]
fn network_call() -> Result<String, TimeoutError> {
    Ok("data".to_string())
}
Commit count: 39

cargo fmt