Expand description
Easy error handling for embedded devices (no liballoc
and no_std
).
Errors are represented by error codes and come from enums that implement the
ErrorCategory
trait (a derive macro exists), which is used for custom debug
printing per error code among other things. Each error code can have a value from 0
to 15
(4 bits) and you can chain an error with up to four different error codes of
different categories.
The Error
type encapsulates an error code and error chain, and is only a single
u32
in size. There is also an untyped DynError
type, which unlike Error
does not have a type parameter for the current error code. Its size is a u32
+
pointer (usize
), which can be used to forward source errors of different categories
to the caller.
This library was inspired by libraries such as
error-chain,
anyhow and
thiserror, though it was made to work in no_std
and no liballoc
environments with very little memory overhead.
§Example
use embedded_error_chain::prelude::*;
#[derive(Clone, Copy, ErrorCategory)]
#[repr(u8)]
enum SpiError {
BusError,
// ...
}
static LAST_GYRO_ACC_READOUT: usize = 200;
#[derive(Clone, Copy, ErrorCategory)]
#[error_category(links(SpiError))]
#[repr(u8)]
enum GyroAccError {
InitFailed,
#[error("{variant} (readout={})", LAST_GYRO_ACC_READOUT)]
ReadoutFailed,
/// Value must be in range [0, 256)
#[error("{variant}: {summary}")]
InvalidValue,
}
fn main() {
if let Err(err) = calibrate() {
// log the error
println!("{:?}", err);
// ...
}
let readout = match gyro_acc_readout() {
Ok(val) => val,
Err(err) => {
if let Some(spi_error) = err.code_of_category::<SpiError>() {
// try to fix it
0
}
else {
panic!("unfixable spi error");
}
}
};
}
fn spi_init() -> Result<(), SpiError> {
Err(SpiError::BusError)
}
fn gyro_acc_init() -> Result<(), Error<GyroAccError>> {
spi_init().chain_err(GyroAccError::InitFailed)?;
Ok(())
}
fn gyro_acc_readout() -> Result<u32, Error<GyroAccError>> {
Err(SpiError::BusError.chain(GyroAccError::InvalidValue))
}
fn calibrate() -> Result<(), DynError> {
gyro_acc_init()?;
// other stuff...
Ok(())
}
Modules§
Structs§
- DynError
- Untyped counterpart to
Error
. - Error
- A typed error with an optional error chain of up to four source errors that represent the cause of this error.
- Error
Category Handle - A handle to a type that implements
ErrorCategory
. - Error
Code Formatter Val - A wrapped
ErrorCodeFormatter
value. - Error
Data - The entire data of the error and its error code chain.
- Error
Iter - An iterator over all error codes in this
Error
.
Constants§
- ERROR_
CHAIN_ LEN - The maximum amount of error codes that can be chained to an
Error
orDynError
.
Traits§
- Chain
Error - A trait that allows chaining of
Error
andDynError
values and any value of a type that implementsErrorCategory
. - Error
Category - A trait that implements the logic for debug printing and
ErrorCode
conversion. It also specifies the links to other error categories that allows errors of different categories to be chained. - Result
Chain Error - A trait that allows chaining if a
Result
contains anError
value.
Functions§
- format_
chained - Debug format the given
error_code
usingf
iff
isSome
, get theErrorCategoryHandle
of the type parameterC
, and get the nextErrorCodeFormatter
ifnext_formatter
isSome
.
Type Aliases§
- Error
Code - An error code belonging to an
ErrorCategory
. - Error
Code Formatter - A chained formatter function for a single error category.
Derive Macros§
- Error
Category - Derive
ErrorCategory
for an enum.