Struct Error

Source
pub struct Error<C>(/* private fields */);
Expand description

A typed error with an optional error chain of up to four source errors that represent the cause of this error.

The error chain is a singly linked list of most recent to oldest source error with a maximum length of 4. When chaining two errors with chain() or chain_err() the error code of the current error is prepended to the front of the linked list. If the linked list is already at its maximum length before chaining, and the feature panic-on-overflow is enabled, the chaining operation will panic, otherwise the oldest error will be lost. After the current error code has been prepended, the new error code will be set as the current and the chain operation will return a new Error typed with the ErrorCategory of the new error code.

Chaining an Error with a new error code is only possible if the ErrorCategory of the new error code links to the ErrorCategory of the current error code. This is done using the links argument in the error_category attribute, if ErrorCategory is implemented using the derive macro.

#[derive(Clone, Copy, ErrorCategory)]
#[repr(u8)]
enum CurrentError {
    Err
}

#[derive(Clone, Copy, ErrorCategory)]
#[error_category(links(CurrentError))]
//               ~~~~~~~~~~~~~~~~~~~
// This allows `CurrentError` to be chained with `NewError`
#[repr(u8)]
enum NewError {
    Err
}

// Chain example
fn do_chain() -> Error<NewError> {
    (CurrentError::Err).chain(NewError::Err)
}

This does not compile:

#[derive(Clone, Copy, ErrorCategory)]
#[repr(u8)]
enum CurrentError {
    Err
}

#[derive(Clone, Copy, ErrorCategory)]
#[repr(u8)]
enum NewError {
    Err
}

// Chain example
fn do_chain() -> Error<NewError> {
    (CurrentError::Err).chain(NewError::Err)
}

Unlike DynError which does not have a type parameter, Error’s type parameter specifies the ErrorCategory of the most recent error (also called current error). This allows the size of this struct to be reduced and so the struct is guaranteed to only be one u32 or 4 bytes in size (the same size as ErrorData), whereas DynError contains an additional pointer (usize).

Additionally because the error category of the first error is known at compile time, this allows for the chain() and chain_err() operations to be error checked at compile time and for them to have a constant execution time O(1).

But a consequence of this type parameter is, that when returning an Error from a function that has to forward multiple errors of different error categories, you must always chain() or chain_err() them. So instead of an inner error being directly forwarded to the caller, you must have a single error of indirection in between.

#[derive(Clone, Copy, ErrorCategory)]
#[repr(u8)]
enum InnerError {
    SomeError
}

#[derive(Clone, Copy, ErrorCategory)]
#[error_category(links(InnerError))]
#[repr(u8)]
enum OuterError {
    Inner
}

fn do_something_that_may_error() -> Result<(), Error<OuterError>> {
    causes_inner_error().chain_err(OuterError::Inner)?;
    // other stuff that causes `OuterError`...
}

If you want to directly forward a single or multiple source errors with different unrelated error categories and you don’t need the advantages outlined above use DynError instead.

Implementations§

Source§

impl<C> Error<C>

Source

pub const fn new_raw(error_code: ErrorCode) -> Error<C>

Create a new Error with an empty chain from the supplied raw error_code.

This function is memory-safe and will never panic, but if error_code is not part the ErrorCategory C the behavior of all method calls on the returned Error is undefined.

Source

pub const fn from_raw(error_data: ErrorData) -> Error<C>

Crate a new Error from raw ErrorData.

This function is memory-safe and will never panic, but if error_data.code() is not part the ErrorCategory C or the contained error chain is invalid, the behavior of all method calls on the returned Error is undefined.

Source§

impl<C> Error<C>

Source

pub const fn chain_capacity(&self) -> usize

Get the capacity of the error chain.

Always returns ERROR_CHAIN_LEN.

Source§

impl<C: ErrorCategory> Error<C>

Source

pub fn new(error_code: C) -> Error<C>

Create a new Error with an empty chain from the supplied error_code.

Source

pub fn code(&self) -> C

Get the error code of the latest error.

Source

pub fn chain_len(&self) -> usize

Get the length of the error chain.

Source

pub fn caused_by<T: ErrorCategory>(&self, error_code: T) -> bool

Query if this error was caused by error_code which belongs to the error category T.

Source

pub fn code_of_category<T: ErrorCategory>(&self) -> Option<T>

Query the error code contained in this error that belongs to the ErrorCategory T. Return None if this error was not caused by the specified error category.

Examples found in repository?
examples/acc_gyro_errors.rs (line 43)
26fn main() {
27    if let Err(err) = calibrate() {
28        // log the error
29        println!("{:?}", err);
30        // ...
31    }
32
33    if let Err(err) = gyro_acc_readout_check() {
34        // log the error
35        println!("{:?}", err);
36        // ...
37    }
38
39    let _readout = match gyro_acc_readout() {
40        Ok(val) => val,
41        Err(err) => {
42            println!("{:?}", err);
43            if let Some(_spi_error) = err.code_of_category::<SpiError>() {
44                // try to fix it
45                0
46            } else {
47                panic!("unfixable spi error");
48            }
49        }
50    };
51}
Source

pub fn iter(&self) -> ErrorIter

Create an iterator that iterates over all error codes in this error.

Trait Implementations§

Source§

impl<C: ErrorCategory> ChainError<C, (L0, Error_t)> for Error<C::L0>

Source§

fn chain(self, error_code: C) -> Error<C>

Chain this error with the supplied error_code. Read more
Source§

impl<C: ErrorCategory> ChainError<C, (L1, Error_t)> for Error<C::L1>

Source§

fn chain(self, error_code: C) -> Error<C>

Chain this error with the supplied error_code. Read more
Source§

impl<C: ErrorCategory> ChainError<C, (L2, Error_t)> for Error<C::L2>

Source§

fn chain(self, error_code: C) -> Error<C>

Chain this error with the supplied error_code. Read more
Source§

impl<C: ErrorCategory> ChainError<C, (L3, Error_t)> for Error<C::L3>

Source§

fn chain(self, error_code: C) -> Error<C>

Chain this error with the supplied error_code. Read more
Source§

impl<C: ErrorCategory> ChainError<C, (L4, Error_t)> for Error<C::L4>

Source§

fn chain(self, error_code: C) -> Error<C>

Chain this error with the supplied error_code. Read more
Source§

impl<C: ErrorCategory> ChainError<C, (L5, Error_t)> for Error<C::L5>

Source§

fn chain(self, error_code: C) -> Error<C>

Chain this error with the supplied error_code. Read more
Source§

impl<C: ErrorCategory> Clone for Error<C>

Source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<C: ErrorCategory> Debug for Error<C>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Debug format this error and its chain.

Delegates to DynError::fmt().

Source§

impl<C: ErrorCategory> From<C> for Error<C>

Source§

fn from(error_code: C) -> Self

Converts to this type from the input type.
Source§

impl<C: ErrorCategory> From<Error<C>> for DynError

Source§

fn from(error: Error<C>) -> Self

Converts to this type from the input type.
Source§

impl<C: ErrorCategory> From<Error<C>> for ErrorData

Source§

fn from(error: Error<C>) -> Self

Converts to this type from the input type.
Source§

impl<C: ErrorCategory> PartialEq for Error<C>

Source§

fn eq(&self, other: &Error<C>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<C: ErrorCategory> Copy for Error<C>

Source§

impl<C: ErrorCategory> Eq for Error<C>

Auto Trait Implementations§

§

impl<C> Freeze for Error<C>

§

impl<C> RefUnwindSafe for Error<C>
where C: RefUnwindSafe,

§

impl<C> Send for Error<C>
where C: Send,

§

impl<C> Sync for Error<C>
where C: Sync,

§

impl<C> Unpin for Error<C>
where C: Unpin,

§

impl<C> UnwindSafe for Error<C>
where C: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.