#error #error-message #error-chain #pretty-print #struct #cli-applications

user-error

UserFacingError 是一个错误crate,它允许你以美观的格式打印错误和错误链,以便最终用户消费。如果你实现了 UFE 特性,默认实现将允许你将错误打印到 TTY。还有一个 UserFacingError 类型,大多数 std Errors 都可以转换成该类型,或者你可以直接使用。

16 个稳定版本

1.2.8 2020 年 5 月 14 日
1.2.7 2020 年 5 月 2 日
1.2.4 2020 年 4 月 29 日
1.1.0 2019 年 12 月 1 日
1.0.1 2019 年 6 月 25 日

#1 in #error-chain

Download history 324/week @ 2024-03-16 312/week @ 2024-03-23 353/week @ 2024-03-30 196/week @ 2024-04-06 277/week @ 2024-04-13 267/week @ 2024-04-20 360/week @ 2024-04-27 250/week @ 2024-05-04 212/week @ 2024-05-11 212/week @ 2024-05-18 191/week @ 2024-05-25 210/week @ 2024-06-01 149/week @ 2024-06-08 179/week @ 2024-06-15 231/week @ 2024-06-22 127/week @ 2024-06-29

每月 709 次下载
用于 11 个 crate(6 个直接使用)

自定义许可协议

37KB
397

UserFacingError

build-status-shield github-issues-open-shield crates-io-version-shield crates-io-downloads-shield license-shield

discord-status-shield twitter-shield

为你的 CLI 应用程序提供美观的错误打印。

此仓库包含

  1. 一个新的特性,UFE,你可以将其实现在你自己的错误类型上以打印它们
  2. 一个新的类型,UserFacingError,你可以用它来构建美观的 CLI 错误消息
  3. 可以将你的错误类型转换为 UserFacingError

UserFacingError 是一个错误类型或特性,它帮助你为 CLI 应用的用户提供格式化和打印美观的错误消息。这些错误旨在供人类消费,而不是你的程序。它们分为三个部分:摘要、原因和帮助文本。

摘要: 表示你的错误单行描述的 String。摘要强制,并以粗体红色打印。

原因: 一个 String 向量,更详细地解释了错误发生的 原因。原因是可选的,如果终端支持颜色,则项目符号('-')将被着色为黄色。每个原因将单独打印。

帮助文本: 一个 String,解释了额外的信息,包括用户可以做什么来处理错误,或者在哪里提交错误报告。帮助文本是可选的,如果终端支持颜色,它将以暗淡的方式打印。

use user_error::UserFacingError;

fn main() {
    UserFacingError::new("Failed to build project") 
        .reason("Database could not be parsed")
        .reason("File \"main.db\" not found") 
        .help("Try: touch main.db")
        .print()
}

这会打印

Error: Failed to build project
- Database could not be parsed
- File "main.db" not found
Try: touch main.db

如果用户在终端上启用了颜色,它可能看起来像这样:Rust 中 user-error 库的快速入门示例

目录

背景

UserFacingError 可以轻松地将错误以合理、美观的格式打印到命令行应用程序的用户。我喜欢 Rust 的 Result 类型,以及使用枚举进行匹配和 &str 进行错误消息。这对开发来说很棒,但不太适合 CLI 应用程序的用户。为此,我创建了一个 UserFacingError,它可以快速构建一个美观的错误消息,适当地通知用户出了什么问题以及他们可以做什么。

安装

将以下内容添加到您的 Cargo.toml 中

[dependencies]
user-error = "1.2.8"

使用方法

UFE 特性

您可以通过实现 UFE 特征来轻松地在自定义错误类型上实现 UFE 特征,允许您将它们以美观的格式打印到 stderr。UFE 特征要求您的类型也实现 Error 特征。

use user_error::{UserFacingError, UFE};

// Custom Error Type
#[derive(Debug)]
struct MyError { mssg: String, src: Option<Box<dyn Error>> }

impl Display for MyError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.mssg.to_string())
    }
}

impl Error for MyError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        self.src.as_deref()
    }
}

impl UFE for MyError {}

fn main() {
    let me = MyError {
        mssg: "Program Failed".into(),
        src: Some(Box::new(MyError {
            mssg: "Reason 1".into(),
            src: Some(Box::new(MyError {
                mssg: "Reason 2".into(),
                src: None,
            })),
        })),
    };

    me.print();
}

这会打印

Error: Program Failed
- Reason 1
- Reason 2

默认实现

您可以可选地实现以下三个函数

  1. .summary() -> String - 返回用作错误摘要的字符串
  2. .reasons() -> Option<Vec<String>> - 可选地返回表示错误原因的字符串 Vec
  3. .helptext() -> Option<String> - 可选地返回表示如何解决错误的字符串
摘要

默认情况下,错误摘要是通过调用 .to_string() 在错误上获得的字符串,并在前面加上 "Error: "。

原因

默认情况下,通过递归调用 .source() 创建原因列表,并为链中的每个错误前加上一个项目符号。

帮助文本

默认情况下,不会向实现 UFE 的自定义类型添加 helptext。您将不得不提供自己的实现,或者调用 .into_ufe() 将您的错误类型转换为 UserFacingError,并使用提供的 .help(&str) 函数添加一个。

特性方法

UFE 提供了三个有用的方法

  1. .print() - 美观地打印错误
  2. .print_and_exit() - 美观地打印错误并终止进程
  3. .into_ufe() - 消费自定义 Error 类型并返回 UserFacingError

您可以重写这些方法,但使用此包就没有多少意义了 :p

这会打印

Error: Program Failed!
 - Bad luck

打印

将 UserFacingError 美观地打印到 stderr。

use user_error::UserFacingError;

fn main() {
    UserFacingError::new("Failed to build project")
        .reason("Database config could not be parsed")
        .reason("`db.config` not found")
        .help("Try: touch db.config")
        .print_and_exit();
}

这会打印

Error: Failed to build project
 - Database config could not be parsed
 - `db.config` not found
Try: touch db.config

打印并退出

由于构建此错误可能是您的程序要做的最后一件事,因此您还可以调用 .print_and_exit() 来打印错误,然后使用状态代码 1 终止进程,以提供便利。

use user_error::UserFacingError;

fn main() {
    UserFacingError::new("Failed to build project")
        .reason("Database config could not be parsed")
        .print_and_exit();
}

这会打印

Error: Failed to build project
 - Database config could not be parsed

转换为 UFE

消耗自定义错误类型并返回 UserFacingError。在退出程序之前,如果要修改摘要、原因列表或帮助文本,则很有用。

use user_error::{UserFacingError, UFE}

fn main() {
    let me = MyError { ... };
    me.into_ufe().help("Added helptext").print();
}

这会打印

Error: Failed to build project
 - Database config could not be parsed

UserFacingError 类型

构造

创建新的 UserFacingError 有两种方式

  1. 使用构建器模式
  2. 从其他 std Errors
构建器模式
use user_error::UserFacingError;

fn main() {
    UserFacingError::new("Failed to build project") 
        .reason("Database could not be parsed")
        .reason("File \"main.db\" not found") 
        .help("Try: touch main.db")
        .print()
}

这会打印

Error: Failed to build project
- Database could not be parsed
- File "main.db" not found
Try: touch main.db

如果用户在终端上启用了颜色,它可能看起来像这样:Rust 中 user-error 库的快速入门示例

从其他错误类型

您还可以从实现 std::error::Error 的其他类型创建 UserFacingError。

摘要将是 error.to_string() 的结果,而原因列表将是通过递归调用 .source() 构造的错误链中的任何错误。

use user_error::UserFacingError;
use std::io::(Error, ErrorKind);

fn main() {
    /* Lose the type */
    fn dyn_error() -> Box<dyn Error> {
        let ioe = Error::new(ErrorKind::Other, "MyError");
        Box::new(ioe)
    }

    /* Convert to UFE */
    let ufe: UserFacingError = dyn_error().into();
}

方法

UserFacingError 有 6 个非构建器方法

  1. .update(&str) - 更改错误摘要
  2. .push(&str) - 更改错误摘要,将以前的摘要添加到原因列表中
  3. .clear_reasons() - 删除所有原因
  4. .clear_help() - 删除帮助文本
  5. .print() - 美化打印错误(使用默认 UFE 实现)
  6. .print_and_exit() - 美化打印错误并终止进程(使用默认 UFE 实现)
更新

您可以在 UserFacingError 上调用 .update(&str) 来更改错误摘要。

use user_error::UserFacingError;

fn do_thing() -> Result<(), UserFacingError> {
    Err(UserFacingError::new("Didn't do the thing!")
        .reason("Just didn't happen"))
}

fn main() {
    match do_thing() {
        Ok(_) => println!("Success!"),
        Err(E) => {
            e.update("Program Failed!").print()
        }
    }
}

这会打印

Error: Program Failed!
 - Just didn't happen
推送

您可以在 UserFacingError 上调用 .push(&str) 来更改错误摘要并将旧错误摘要添加到原因列表中。它将摘要添加到原因列表的前面。

use user_error::UserFacingError;

fn do_thing() -> Result<(), UserFacingError> {
    Err(UserFacingError::new("Didn't do the thing!")
        .reason("Just didn't happen"))
}

fn main() {
    match do_thing() {
        Ok(_) => println!("Success!"),
        Err(E) => {
            e.update("Program Failed!").print()
        }
    }
}

这会打印

Error: Program Failed!
 - Didn't do the thing!
 - Just didn't happen
清除原因

调用此方法将删除 UserFacingError 中的所有原因。

use user_error::UserFacingError;

fn main() {
    let ufe = UserFacingError::new("Program Failed!")
                .reason("Program internal error message");
    /* --- */

    ufe.clear_reasons();
    ufe.print_and_exit();
}

这会打印

Error: Program Failed!
清除帮助文本

调用此方法将删除 UserFacingError 中的帮助文本。

use user_error::UserFacingError;

fn main() {
    let ufe = UserFacingError::new("Program Failed!")
                .reason("Bad luck")
                .help("Try running it again?");
    /* --- */

    ufe.clear_help();
    ufe.print_and_exit();
}

这会打印

Error: Program Failed!
 - Bad luck

维护者

贡献

请随意深入了解! 打开问题 或提交 PRs。

贡献者

许可证

MIT © Amy Jie

无运行时依赖