gix-error 0.0.0

A crate of the gitoxide project to provide common errors and error-handling utilities
Documentation

Common error types and utilities for error handling.

Usage

  • When there is no callee error to track, use simple std::error::Error implementations directly, e.g. Result<_, Simple>.
  • When there is callee error to track in a gix-plumbing, use e.g. Result<_, Exn<Simple>>.
    • Remember that Exn<T> does not implement std::error::Error so it's not easy to use outside gix- crates.
    • Use the type-erased version in callbacks like [Exn] (without type arguments), i.e. Result<T, Exn>.
  • When there is callee error to track in the gix crate, convert both std::error::Error and Exn<E> into [Error]

Standard Error Types

These should always be used if they match the meaning of the error well enough instead of creating an own Error-implementing type, and used with ResultExt::or_raise(<StandardErrorType>) or OptionExt::ok_or_raise(<StandardErrorType>), or sibling methods.

All these types implement Error.

[Message]

The baseline that provides a formatted message. Formatting can more easily be done with the [message!] macro as convenience, roughly equivalent to Message::new(format!("…")) or format!("…").into().

Specialised types

  • [ParseError]
    • like [Message], but can optionally store the input that caused the failure.

Exn<ErrorType> and [Exn]

The [Exn] type does not implement Error itself, but is able to store causing errors via [ResultExt::or_raise()] (and sibling methods) as well as location information of the creation site.

While plumbing functions that need to track causes should always return a distinct type like Exn<Message>, if that's not possible, use [Exn::erased] to let it return Result<T, Exn> instead, allowing any return type.

A side effect of this is that any callee that causes errors needs to be annotated with .or_raise(|| message!("context information")) or .or_raise_erased(|| message!("context information")).

Feature Flags

Why not anyhow?

anyhow is a proven and optimized library, and it would certainly suffice for an error-chain based approach where users are expected to downcast to concrete types.

What's missing though is track-caller which will always capture the location of error instantiation, along with compatibility for error trees, which are happening when multiple calls are in flight during concurrency.

Both libraries share the shortcoming of not being able to implement std::error::Error on their error type, and both provide workarounds.

exn is much less optimized, but also costs only a Box on the stack, which in any case is a step up from thiserror which exposed a lot of heft to the stack.