Skip to content

Version 0.2.0

Choose a tag to compare

@notheotherben notheotherben released this 03 Dec 13:46
· 71 commits to main since this release
f2cf0ee

⚠️ This is a major breaking change which will require you to rewrite your code if you chose to adopt it (we will continue to maintain the v0.1.x branch which offers a different approach to this problem).

The major difference here is a shift away from using a custom error type (generated using the error_shim!(...) macro in v0.1) to instead using a standard error type with better support for providing additional advice, and improved interoperability with the standard library's Error type. We've also shifted from using impl From<E> for MyErrorType as the primary means of wrapping errors to instead providing extensions for Results<T, E> which simplify wrapping errors with contextual advice (a pattern which was used extensively within codebases implementing human_errors).

What's Changed

  • refactor: Redesign how we handle errors, enabling richer advice and easier extensibility by @notheotherben in #30

Before

use human_errors;
use std::fs;

human_errors::error_shim!(MyError);

fn read_config() -> Result<String, MyError> {
    fs::read_to_string("config.toml").map_err(|err| {
        user_with_internal(
            "We could not read the configuration file.",
            "Make sure that you've specified a valid config file with the --config option.",
            err
        )
    })
}

After

use human_errors::ResultExt;
use std::fs;

fn read_config() -> Result<String, human_errors::Error> {
    fs::read_to_string("config.toml").wrap_err_as_user(
      "We could not read the configuration file.",
      &["Make sure that you've specified a valid config file with the --config option."])
}

Migration Instructions

  1. Remove any human_errors::error_shim!(MyErrorType) usage and replace all usage of MyErrorType with human_errors::Error.
  2. Replace any calls to human_errors::description(msg) with msg) (conversion happens automatically).
  3. Replace any calls to human_errors::user(msg, advice) with human_errors::user(msg, &[advice]).
  4. Replace any calls to human_errors::system(msg, advice) with human_errors::system(msg, &[advice]).
  5. Replace any calls to human_errors::user_with_internal(msg, advice, err) with human_errors::wrap_user(err, msg, &[advice]).
  6. Replace any calls to human_errors::system_with_internal(msg, advice, err) with human_errors::wrap_system(err, msg, &[advice]).
  7. Replace code using the .map_err(|e| human_errors::user_with_internal(msg, advice, e)) pattern with .wrap_err_as_user(msg, &[advice]).
  8. Replace code using the .map_err(|e| human_errors::system_with_internal(msg, advice, e)) pattern with .wrap_err_as_system(msg, &[advice]).

Removed Functionality

  • We no longer support implementing custom From<T> conversions, instead you should wrap errors in contextual advice using any of the user, system, wrap_user, and wrap_system methods.
  • We no longer provide the ability to generate dynamic advice at runtime, relying on &'static [&'static str] advice lists for performance reasons. Instead, you can incorporate any dynamic context into the error message using the wrap_user(...) and wrap_system(...) methods.

Full Changelog: v0.1.7...v0.2.0