narrate 0.1.1

narrate is a set of CLI app utilities for error handling and status reporting
Documentation

narrate

This library provides CLI application error and status reporting utilities. The coloured output formatting aims to be similar to Cargo. Error type is a wrapper around Anyhow.

Crates.io tests license

Features

  • Wrap any error with additional context
  • Optional help messages for errors
  • Set of standard CLI errors with exit codes conforming to sysexits.h
  • Convenience Result type

Planned features

  • Error chain output
  • Status messages

How to use

  • Use narrate::Result<T> as a return type of any fallible function.

    Within the function, use ? to propagate any error that implements the std::error::Error trait. Same as anyhow::Result<T>.

    use narrate::Result;
    
    fn get_user() -> Result<User> {
        let json = std::fs::read_to_string("user.json")?;
        let user: User = serde_json::from_str(&json)?;
        Ok(user)
    }
    
  • Wrap an error with more context by importing the narrate::ErrorWrap trait. Similar to anyhow::Context, this can give your users more information as to why an error happened.

    use narrate::{CliError, ErrorWrap, Result};
    
    fn run() -> Result<()> {
        ...
        // wrap with contextual information
        data.acquire().wrap(|| "unable to aquire data")?;
    
        // wrap with another error
        config.load().wrap(|| CliError::Config)?;
    
        // wrap with help information
        create_dir().wrap_help(|| "project directory already exists", "try using cargo init")?;
        ...
    }
    
    error: project directory already exists
    cause: Is a directory (os error 20)
    
    help: try using cargo init
    
  • Use the narrate::ExitCode trait to get the sysexits.h conforming exit code from a narrate::Error. By default this is just 70 (software error) but it can be easily implemented for any type.

  • narrate::CliError collection of typical command line errors. Use them to add context to deeper application errors. Use their exit_code to conform to sysexits.h.

    use narrate::{CliError, ErrorWrap, ExitCode, Result};
    
    fn main() {
        let res = run();
    
        if let Err(ref err) = res {
            std::process::exit(err.exit_code());
        }
    }
    
    fn run() -> Result<()> {
        will_error().wrap(|| CliError::OsErr)?
        Ok(())
    }
    

License

narrate is distributed under the terms of both the MIT license and the Apache License (Version 2.0).

See LICENSE-APACHE and LICENSE-MIT for details.