Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/cristicbz/failchain
failure + error-chain = 💖
https://github.com/cristicbz/failchain
Last synced: about 1 month ago
JSON representation
failure + error-chain = 💖
- Host: GitHub
- URL: https://github.com/cristicbz/failchain
- Owner: cristicbz
- License: apache-2.0
- Created: 2019-04-05T19:11:41.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2021-04-02T16:25:07.000Z (over 3 years ago)
- Last Synced: 2024-08-09T03:07:13.010Z (about 1 month ago)
- Language: Rust
- Size: 13.7 KB
- Stars: 54
- Watchers: 4
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
failchain
---* [crates.io](https://crates.io/crates/failchain)
* [Documentation](https://docs.rs/failchain)`failchain` is a tiny companion crate to the [`failure`](https://boats.gitlab.io/failure/intro.html)
crate, which aims to recover the ergonomics of
[`error_chain`](https://github.com/rust-lang-nursery/error-chain). It does this
by bringing back:
* `chain_err`
* non-verbose `Error`, `ErrorKind` pairs
* support for `bail!` and `ensure!` with custom `ErrorKind`-sThe `failure` library recommends three different patterns for errors. This
library implementes the most complex one (and the most useful one) but without all the [boilerplate](https://boats.gitlab.io/failure/error-errorkind.html).### What it looks like
```rust
// errors.rs
use failchain::{BoxedError, ChainErrorKind};
use failure::Fail;
use std::path::PathBuf;
use std::result::Result as StdResult;pub type Error = BoxedError; // Use `UnboxedError` instead for
// non-allocating, but bigger `Error`.
pub type Result = StdResult;#[derive(Clone, Eq, PartialEq, Debug, Fail)]
pub enum ErrorKind {
#[fail(display = "Metadata I/O error {:?}.", 0)]
MetadataIo(PathBuf),#[fail(display = "Corrupt metadata file: {}", 0)]
CorruptMetadata(String),#[fail(display = "WAD I/O error {:?}.", 0)]
WadIo(PathBuf),#[fail(display = "Corrupt WAD file: {}", 0)]
CorruptWad(String),
}impl ChainErrorKind for ErrorKind {
type Error = Error;
}// main.rs
use super::errors::{ErrorKind, Result};
use failchain::{
bail,
ensure,
ResultExt, // for `chain_err`,
};
use std::fs::File;
use std::io::Read;
use std::path::Path;fn validate_metadata(path: &Path, metadata: &str) -> Result<()> {
// `ensure` is like `assert` (or failure's ensure), except it allows you to
// specify the `ErrorKind`.
ensure!(
!metadata.is_empty(),
ErrorKind::CorruptMetadata(format!("metadata file {:?} is empty", path))
);// a special mode of `ensure` works for functions that return `ErrorKind`-s
// and take a single string as argument:
ensure!(
metadata.len() > 100,
ErrorKind::CorruptMetadata, // Any FnOnce(String) -> ErrorKind
"metadata file {:?} is too long", // Rest of arguments are format args.
path,
);// `bail` is like `ensure`, but without the condition and always returns
// early.
bail!(
ErrorKind::CorruptMetadata,
"validation isn't actually implemented"
);
}fn load(wad: &Path, metadata: &Path) -> Result<()> {
// `chain_err` stashes the original error as the `cause` of a new error.
let wad_file = File::open(wad).chain_err(|| ErrorKind::WadIo(wad.to_owned()))?;let mut metadata_content = String::new();
// `chain_inspect_err` stashes the original error as the `cause` of the new
// error, but it first allows the callback to inspect it.
let metadata_file = File::open(metadata)
.and_then(|mut file| file.read_to_string(&mut metadata_content))
.chain_inspect_err(|_io_error| ErrorKind::MetadataIo(metadata.to_owned()))?;validate_metadata(metadata, &metadata_content)?;
Ok(())
}
```### Future Plans
This library is a proof-of-concept and was developed as part of the `error_chain` ->
`failure` migration of [rust-doom](https://github.com/cristicbz/rust-doom) and inspired by
@burntsushi's error handling solution in [imdb-rename](https://github.com/BurntSushi/imdb-rename/blob/master/imdb-index/src/error.rs
).The main issue with the current library is that `failchain` must be leaked as a public dependency
via the `Error` type-alias. This would be easily solved with a custom derive which implements the
necessary `From` and `Fail` impl-s e.g.
```rust
#[derive(ChainError)]
pub struct Error(BoxedError);// expanding to
impl Fail for Error { /* delegate */ }
impl From for Error { /* delegate */ }
```The error handling story in Rust is a little up in the air right now, but in my opinion any eventual
solution should include these pieces (as `error_chain` did).### Versioning
`failure` is a public dependency of `failchain`. The library versioning scheme is
``. So `0.1015.2` would be version `0.1.2` of
`failchain` with a dependency on version `0.1.5` of `failure`.