15 releases (7 stable)

1.0.6 Sep 1, 2024
0.1.7 Feb 16, 2024
0.1.6 Dec 30, 2023
0.1.0 Dec 22, 2022

#296 in Rust patterns

45 downloads per month

Apache-2.0

11KB
116 lines

SmartErr

SmartErr, an error handling library, introduces several convenient aproaches to define, raise and handle domain-specific errors in libraries and/or applications.

With SmartErr it is possible to:

  • raise errors with raise and throw methods on regular types (numbers, strings, boolean, Option, Result, etc) as an error source. Look into Raising errors section to find out more details.
  • define atomic errors with error! macro (requires atomic_error feature).
  • define the exact set of errors emitted by the function or introduce global set for the public API (requires erorrset feature).

Defining atomic errors

With atomic_error feature enabled (it is also included into smarterr feature), it is possible to define atomic errors, which are structs, annotated with thiserror::Error attribute. For instance, the following definition:

error!(pub InvalidData<ParseIntError> { pub data: String } => "Invalid data provided [data={data}]");

will generate the code:

#[derive(thiserror::Error, Debug)]
#[error("Invalid data provided [data={data}]")]
pub struct InvalidData {
    pub data: String,
    #[source]
    pub source: ParseIntError,
}

Raising or throwing errors

Sometimes functions may return simple types instead of Result. Library provides a set of methods to convert these types into Result based on the convention what values should be treated as an error:

Source type error state for the type
numbers (i32, usize, etc) != 0
bool false
strings (&str, String etc) is_empty()
Option None
Result Err

Further actions depend on the function used to convert the value into Result:

throw - does NOT change error context. When the error state is detected, the value is mapped with the provided err_map function and returned as Err(err_map(original_value)). Otherwise, the original value is just wrapped into Result::Ok.

raise - CHANGES error context. When the error state is detected, the original value is wrapped into Result::Ok. Otherwise, the value is mapped with the provided ok_to_err_map function and returned as Err(ok_to_err_map(original_value)).

Defining output error set

With errorset feature enabled, it is possible to define a set of errors emitted by the function. The errorset macro generates a new error type that contains all the errors from the function signature.

You may find more details in the ErrorSet crate documentation.

SmartErr crate reexports ErrorSet crate, so you may use it functionality directly.

For instance, the following code:

#[errorset]
pub fn parse_u32(data: &str) -> Result<u32, (InvalidData, OutOfBounds)> {
    ...
}

will produce the code:

#[derive(::thiserror::Error, Debug)]
pub enum ParseU32Errors {
    #[error(transparent)]
    InvalidData(#[from] InvalidData),
    #[error(transparent)]
    OutOfBounds(#[from] OutOfBounds),
}
impl _SomeStruct {
    fn parse_u32(data: &str) -> Result<u32, ParseU32Errors> {
        ...
    }
}

Dependencies

~205KB