Struct DynError

Source
pub struct DynError { /* private fields */ }
Expand description

Untyped counterpart to Error.

This struct functions mostly identical to Error though its contained error code can be of any ErrorCategory and does not depend on a type parameter. To enable this, this struct in addition to an ErrorData value also contains an ErrorCodeFormatter function pointer belonging to the ErrorCategory of the most recent error.

All the limitation to error chaining outlined in Error’s documentation also apply to DynError. But because the error category type of this error is not known, whether or not it is possible to chain a DynError using chain() or chain_err() with an different error_code cannot be checked at compile time. So instead of a compile error it will cause a panic if unlinked error categories are chained.

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

#[derive(Clone, Copy, ErrorCategory)]
#[error_category(links(FooError))]
#[repr(u8)]
enum BarError {
    Err
}

fn cause_dyn_error() -> DynError {
    (FooError::Err).into()
}

// Chain example
fn do_chain() -> DynError {
    cause_dyn_error().chain(BarError::Err).into()
}

This will panic:

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

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

fn cause_dyn_error() -> DynError {
    (FooError::Err).into()
}

fn do_chain() -> DynError {
    cause_dyn_error().chain(BarError::Err).into()
}

Note also the .into() after chaining. This is required because chaining results in an Error<BarError> value being returned. This is also true for chain_err().

fn cause_dyn_error_result() -> Result<(), DynError> {
    Err((FooError::Err).into())
}

fn do_chain() -> Result<(), DynError> {
    cause_dyn_error_result().chain_err(BarError::Err)?;
    Ok(())
}

Here we use the property of the ? operator that automatically converts the Error<BarError> to a DynError using .into(). This works because DynError implements the From trait for any Error<T>.

The following would not work and won’t compile:

fn do_chain() -> Result<(), DynError> {
    cause_dyn_error_result().chain_err(BarError::Err)
}

Implementations§

Source§

impl DynError

Source

pub fn new<C: ErrorCategory>(error_code: C) -> DynError

Create a DynError from an error_code belonging to error category C.

Source

pub fn from_raw_parts( error_data: ErrorData, category_formatter: ErrorCodeFormatter, ) -> DynError

Create a DynError from its raw parts.

Source

pub fn into_raw_parts(self) -> (ErrorData, ErrorCodeFormatter)

Turn this dynamic error into its raw parts.

Source

pub fn code(&self) -> ErrorCode

Get the error code of the most recent error.

Source

pub fn chain_len(&self) -> usize

Get the length of the error chain.

Source

pub const fn chain_capacity(&self) -> usize

Get the capacity of the error chain.

Always returns ERROR_CHAIN_LEN.

Source

pub fn category_handle(&self) -> ErrorCategoryHandle

Get the ErrorCategoryHandle of the most recent error.

Source

pub fn formatter(&self) -> ErrorCodeFormatter

Get the ErrorCodeFormatter function of the most recent error.

Source

pub fn is<C: ErrorCategory>(&self) -> bool

Return true if the most recent error code belongs to the error category C.

Source

pub fn try_into<C: ErrorCategory>(self) -> Result<Error<C>, Self>

Try to convert this untyped dynamic error into a statically typed error.

Succeeds and returns the equivalent Error of this DynError if self.is::<C>() returns true, otherwise returns an Err containing the original DynError.

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 (error category)ErrorCategory T. Return None if this error was not caused by the specified error category.

Source

pub fn iter(&self) -> ErrorIter

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

Source

pub fn try_chain<C: ErrorCategory>( self, error_code: C, ) -> Result<Error<C>, Self>

Try to chain this dynamically typed DynError with error_code of error category C.

A call to this function only succeeds if the slice of ErrorCodeFormatters returned by C::chainable_category_formatters() contains self.formatter().

Note that this function has time complexity O(n) where n is the length of the slice returned by C::chainable_category_formatters().

Trait Implementations§

Source§

impl<O: ErrorCategory> ChainError<O, DynError> for DynError

Source§

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

Chain a DynError with any error code of a linked ErrorCategory.

Note that this function has complexity O(n) where n is the length of the slice returned by O::chainable_category_formatters().

§Panics

A call to this function panics if the slice of ErrorCodeFormatters returned by O::chainable_category_formatters() does not contain self.formatter().

Source§

impl Clone for DynError

Source§

fn clone(&self) -> DynError

Returns a copy of the value. Read more
1.0.0 · Source§

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

Performs copy-assignment from source. Read more
Source§

impl Debug for DynError

Source§

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

Debug format this error and its chain.

Error message example:

ControlTaskError(0): init failed
- ICM20689Error(0): init failed
- SpiError(0): bus error
Source§

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

Source§

fn from(error: 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 PartialEq for DynError

Source§

fn eq(&self, other: &DynError) -> 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 Eq for DynError

Auto Trait Implementations§

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.